get agpmode from config file
[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
225 /* Initialize and start the CP if required */
226 if ((err = drmCommandNone(ctx->drmFD, DRM_RADEON_CP_START)) != 0) {
227 fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
228 return 0;
229 }
230
231 return 1;
232 }
233
234
235 /**
236 * \brief Shutdown the drawing engine.
237 *
238 * \param ctx display handle
239 *
240 * Turns off the command processor engine & restores the graphics card
241 * to a state that fbdev understands.
242 */
243 static int RADEONEngineShutdown( const DRIDriverContext *ctx )
244 {
245 drm_radeon_cp_stop_t stop;
246 int ret, i;
247
248 stop.flush = 1;
249 stop.idle = 1;
250
251 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
252 sizeof(drm_radeon_cp_stop_t));
253
254 if (ret == 0) {
255 return 0;
256 } else if (errno != EBUSY) {
257 return -errno;
258 }
259
260 stop.flush = 0;
261
262 i = 0;
263 do {
264 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
265 sizeof(drm_radeon_cp_stop_t));
266 } while (ret && errno == EBUSY && i++ < 10);
267
268 if (ret == 0) {
269 return 0;
270 } else if (errno != EBUSY) {
271 return -errno;
272 }
273
274 stop.idle = 0;
275
276 if (drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP,
277 &stop, sizeof(drm_radeon_cp_stop_t))) {
278 return -errno;
279 } else {
280 return 0;
281 }
282 }
283
284 /**
285 * \brief Compute base 2 logarithm.
286 *
287 * \param val value.
288 *
289 * \return base 2 logarithm of \p val.
290 */
291 static int RADEONMinBits(int val)
292 {
293 int bits;
294
295 if (!val) return 1;
296 for (bits = 0; val; val >>= 1, ++bits);
297 return bits;
298 }
299
300 /**
301 * \brief Initialize the AGP state
302 *
303 * \param ctx display handle.
304 * \param info driver private data.
305 *
306 * \return one on success, or zero on failure.
307 *
308 * Acquires and enables the AGP device. Reserves memory in the AGP space for
309 * the ring buffer, vertex buffers and textures. Initialize the Radeon
310 * registers to point to that memory and add client mappings.
311 */
312 static int RADEONDRIAgpInit( const DRIDriverContext *ctx, RADEONInfoPtr info)
313 {
314 unsigned char *RADEONMMIO = ctx->MMIOAddress;
315 unsigned long mode;
316 int ret;
317 int s, l;
318
319 if (drmAgpAcquire(ctx->drmFD) < 0) {
320 fprintf(stderr, "[gart] AGP not available\n");
321 return 0;
322 }
323
324 /* Modify the mode if the default mode is not appropriate for this
325 * particular combination of graphics card and AGP chipset.
326 */
327 mode = drmAgpGetMode(ctx->drmFD); /* Default mode */
328
329 /* Disable fast write entirely - too many lockups.
330 */
331 mode &= ~RADEON_AGP_MODE_MASK;
332 switch (ctx->agpmode) {
333 case 4: mode |= RADEON_AGP_4X_MODE;
334 case 2: mode |= RADEON_AGP_2X_MODE;
335 case 1: default: mode |= RADEON_AGP_1X_MODE;
336 }
337
338 if (drmAgpEnable(ctx->drmFD, mode) < 0) {
339 fprintf(stderr, "[gart] AGP not enabled\n");
340 drmAgpRelease(ctx->drmFD);
341 return 0;
342 }
343 else
344 fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);
345
346 /* Workaround for some hardware bugs */
347 if (info->ChipFamily < CHIP_FAMILY_R200)
348 OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
349
350 info->gartOffset = 0;
351
352 if ((ret = drmAgpAlloc(ctx->drmFD, info->gartSize*1024*1024, 0, NULL,
353 &info->gartMemHandle)) < 0) {
354 fprintf(stderr, "[gart] Out of memory (%d)\n", ret);
355 drmAgpRelease(ctx->drmFD);
356 return 0;
357 }
358 fprintf(stderr,
359 "[gart] %d kB allocated with handle 0x%08x\n",
360 info->gartSize*1024, (unsigned)info->gartMemHandle);
361
362 if (drmAgpBind(ctx->drmFD,
363 info->gartMemHandle, info->gartOffset) < 0) {
364 fprintf(stderr, "[gart] Could not bind\n");
365 drmAgpFree(ctx->drmFD, info->gartMemHandle);
366 drmAgpRelease(ctx->drmFD);
367 return 0;
368 }
369
370 /* Initialize the CP ring buffer data */
371 info->ringStart = info->gartOffset;
372 info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
373
374 info->ringReadOffset = info->ringStart + info->ringMapSize;
375 info->ringReadMapSize = DRM_PAGE_SIZE;
376
377 /* Reserve space for vertex/indirect buffers */
378 info->bufStart = info->ringReadOffset + info->ringReadMapSize;
379 info->bufMapSize = info->bufSize*1024*1024;
380
381 /* Reserve the rest for AGP textures */
382 info->gartTexStart = info->bufStart + info->bufMapSize;
383 s = (info->gartSize*1024*1024 - info->gartTexStart);
384 l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
385 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
386 info->gartTexMapSize = (s >> l) << l;
387 info->log2GARTTexGran = l;
388
389 if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
390 DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) {
391 fprintf(stderr, "[gart] Could not add ring mapping\n");
392 return 0;
393 }
394 fprintf(stderr, "[gart] ring handle = 0x%08lx\n", info->ringHandle);
395
396
397 if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
398 DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {
399 fprintf(stderr,
400 "[gart] Could not add ring read ptr mapping\n");
401 return 0;
402 }
403
404 fprintf(stderr,
405 "[gart] ring read ptr handle = 0x%08lx\n",
406 info->ringReadPtrHandle);
407
408 if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
409 DRM_AGP, 0, &info->bufHandle) < 0) {
410 fprintf(stderr,
411 "[gart] Could not add vertex/indirect buffers mapping\n");
412 return 0;
413 }
414 fprintf(stderr,
415 "[gart] vertex/indirect buffers handle = 0x%08lx\n",
416 info->bufHandle);
417
418 if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,
419 DRM_AGP, 0, &info->gartTexHandle) < 0) {
420 fprintf(stderr,
421 "[gart] Could not add AGP texture map mapping\n");
422 return 0;
423 }
424 fprintf(stderr,
425 "[gart] AGP texture map handle = 0x%08lx\n",
426 info->gartTexHandle);
427
428 /* Initialize Radeon's AGP registers */
429 /* Ring buffer is at AGP offset 0 */
430 OUTREG(RADEON_AGP_BASE, info->ringHandle);
431
432 return 1;
433 }
434
435
436 /**
437 * \brief Initialize the kernel data structures and enable the CP engine.
438 *
439 * \param ctx display handle.
440 * \param info driver private data.
441 *
442 * \return non-zero on success, or zero on failure.
443 *
444 * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
445 * all the parameters in a drm_radeon_init_t structure.
446 */
447 static int RADEONDRIKernelInit( const DRIDriverContext *ctx,
448 RADEONInfoPtr info)
449 {
450 int cpp = ctx->bpp / 8;
451 drm_radeon_init_t drmInfo;
452 int ret;
453
454 memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
455
456 if ( (info->ChipFamily == CHIP_FAMILY_R200) ||
457 (info->ChipFamily == CHIP_FAMILY_RV250) ||
458 (info->ChipFamily == CHIP_FAMILY_M9) ||
459 (info->ChipFamily == CHIP_FAMILY_RV280) )
460 drmInfo.func = RADEON_INIT_R200_CP;
461 else
462 drmInfo.func = RADEON_INIT_CP;
463
464 /* This is the struct passed to the kernel module for its initialization */
465 drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
466 drmInfo.is_pci = 0;
467 drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE;
468 drmInfo.gart_size = info->gartSize*1024*1024;
469 drmInfo.ring_size = info->ringSize*1024*1024;
470 drmInfo.usec_timeout = 1000;
471 drmInfo.fb_bpp = ctx->bpp;
472 drmInfo.depth_bpp = ctx->bpp;
473 drmInfo.front_offset = info->frontOffset;
474 drmInfo.front_pitch = info->frontPitch * cpp;
475 drmInfo.back_offset = info->backOffset;
476 drmInfo.back_pitch = info->backPitch * cpp;
477 drmInfo.depth_offset = info->depthOffset;
478 drmInfo.depth_pitch = info->depthPitch * cpp;
479 drmInfo.fb_offset = info->LinearAddr;
480 drmInfo.mmio_offset = info->registerHandle;
481 drmInfo.ring_offset = info->ringHandle;
482 drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
483 drmInfo.buffers_offset = info->bufHandle;
484 drmInfo.gart_textures_offset = info->gartTexHandle;
485
486 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo,
487 sizeof(drm_radeon_init_t));
488
489 return ret >= 0;
490 }
491
492
493 /**
494 * \brief Initialize the AGP heap.
495 *
496 * \param ctx display handle.
497 * \param info driver private data.
498 *
499 * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
500 * all the parameters in a drm_radeon_mem_init_heap structure.
501 */
502 static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx,
503 RADEONInfoPtr info)
504 {
505 drm_radeon_mem_init_heap_t drmHeap;
506
507 /* Start up the simple memory manager for gart space */
508 drmHeap.region = RADEON_MEM_REGION_GART;
509 drmHeap.start = 0;
510 drmHeap.size = info->gartTexMapSize;
511
512 if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP,
513 &drmHeap, sizeof(drmHeap))) {
514 fprintf(stderr,
515 "[drm] Failed to initialized gart heap manager\n");
516 } else {
517 fprintf(stderr,
518 "[drm] Initialized kernel gart heap manager, %d\n",
519 info->gartTexMapSize);
520 }
521 }
522
523 /**
524 * \brief Add a map for the vertex buffers that will be accessed by any
525 * DRI-based clients.
526 *
527 * \param ctx display handle.
528 * \param info driver private data.
529 *
530 * \return one on success, or zero on failure.
531 *
532 * Calls drmAddBufs() with the previously allocated vertex buffers.
533 */
534 static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
535 {
536 /* Initialize vertex buffers */
537 info->bufNumBufs = drmAddBufs(ctx->drmFD,
538 info->bufMapSize / RADEON_BUFFER_SIZE,
539 RADEON_BUFFER_SIZE,
540 DRM_AGP_BUFFER,
541 info->bufStart);
542
543 if (info->bufNumBufs <= 0) {
544 fprintf(stderr,
545 "[drm] Could not create vertex/indirect buffers list\n");
546 return 0;
547 }
548 fprintf(stderr,
549 "[drm] Added %d %d byte vertex/indirect buffers\n",
550 info->bufNumBufs, RADEON_BUFFER_SIZE);
551
552 return 1;
553 }
554
555 /**
556 * \brief Install an IRQ handler.
557 *
558 * \param ctx display handle.
559 * \param info driver private data.
560 *
561 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
562 * IRQ-free operation on failure.
563 */
564 static void RADEONDRIIrqInit(const DRIDriverContext *ctx,
565 RADEONInfoPtr info)
566 {
567 if (!info->irq) {
568 info->irq = drmGetInterruptFromBusID(ctx->drmFD,
569 ctx->pciBus,
570 ctx->pciDevice,
571 ctx->pciFunc);
572
573 if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
574 fprintf(stderr,
575 "[drm] failure adding irq handler, "
576 "there is a device already using that irq\n"
577 "[drm] falling back to irq-free operation\n");
578 info->irq = 0;
579 }
580 }
581
582 if (info->irq)
583 fprintf(stderr,
584 "[drm] dma control initialized, using IRQ %d\n",
585 info->irq);
586 }
587
588 static int RADEONCheckDRMVersion( const DRIDriverContext *ctx,
589 RADEONInfoPtr info )
590 {
591 drmVersionPtr version;
592
593 version = drmGetVersion(ctx->drmFD);
594 if (version) {
595 int req_minor, req_patch;
596
597 /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
598 */
599 req_minor = 8;
600 req_patch = 0;
601
602 if (version->version_major != 1 ||
603 version->version_minor < req_minor ||
604 (version->version_minor == req_minor &&
605 version->version_patchlevel < req_patch)) {
606 /* Incompatible drm version */
607 fprintf(stderr,
608 "[dri] RADEONDRIScreenInit failed because of a version "
609 "mismatch.\n"
610 "[dri] radeon.o kernel module version is %d.%d.%d "
611 "but version 1.%d.%d or newer is needed.\n"
612 "[dri] Disabling DRI.\n",
613 version->version_major,
614 version->version_minor,
615 version->version_patchlevel,
616 req_minor,
617 req_patch);
618 drmFreeVersion(version);
619 return 0;
620 }
621
622 info->drmMinor = version->version_minor;
623 drmFreeVersion(version);
624 }
625
626 return 1;
627 }
628
629 static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
630 {
631 int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
632 int cpp = ctx->cpp;
633 int bufferSize = ((ctx->shared.virtualHeight * width_bytes
634 + RADEON_BUFFER_ALIGN)
635 & ~RADEON_BUFFER_ALIGN);
636 int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
637 + RADEON_BUFFER_ALIGN)
638 & ~RADEON_BUFFER_ALIGN);
639 int l;
640
641 info->frontOffset = 0;
642 info->frontPitch = ctx->shared.virtualWidth;
643
644 fprintf(stderr,
645 "Using %d MB AGP aperture\n", info->gartSize);
646 fprintf(stderr,
647 "Using %d MB for the ring buffer\n", info->ringSize);
648 fprintf(stderr,
649 "Using %d MB for vertex/indirect buffers\n", info->bufSize);
650 fprintf(stderr,
651 "Using %d MB for AGP textures\n", info->gartTexSize);
652
653 /* Front, back and depth buffers - everything else texture??
654 */
655 info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
656
657 if (info->textureSize < 0)
658 return 0;
659
660 l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
661 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
662
663 /* Round the texture size up to the nearest whole number of
664 * texture regions. Again, be greedy about this, don't
665 * round down.
666 */
667 info->log2TexGran = l;
668 info->textureSize = (info->textureSize >> l) << l;
669
670 /* Set a minimum usable local texture heap size. This will fit
671 * two 256x256x32bpp textures.
672 */
673 if (info->textureSize < 512 * 1024) {
674 info->textureOffset = 0;
675 info->textureSize = 0;
676 }
677
678 /* Reserve space for textures */
679 info->textureOffset = ((ctx->shared.fbSize - info->textureSize +
680 RADEON_BUFFER_ALIGN) &
681 ~RADEON_BUFFER_ALIGN);
682
683 /* Reserve space for the shared depth
684 * buffer.
685 */
686 info->depthOffset = ((info->textureOffset - depthSize +
687 RADEON_BUFFER_ALIGN) &
688 ~RADEON_BUFFER_ALIGN);
689 info->depthPitch = ctx->shared.virtualWidth;
690
691 info->backOffset = ((info->depthOffset - bufferSize +
692 RADEON_BUFFER_ALIGN) &
693 ~RADEON_BUFFER_ALIGN);
694 info->backPitch = ctx->shared.virtualWidth;
695
696
697 fprintf(stderr,
698 "Will use back buffer at offset 0x%x\n",
699 info->backOffset);
700 fprintf(stderr,
701 "Will use depth buffer at offset 0x%x\n",
702 info->depthOffset);
703 fprintf(stderr,
704 "Will use %d kb for textures at offset 0x%x\n",
705 info->textureSize/1024, info->textureOffset);
706
707 info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
708 (info->frontOffset >> 10));
709
710 info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
711 (info->backOffset >> 10));
712
713 info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
714 (info->depthOffset >> 10));
715
716 return 1;
717 }
718
719
720
721 /**
722 * Called at the start of each server generation.
723 *
724 * \param ctx display handle.
725 * \param info driver private data.
726 *
727 * \return non-zero on success, or zero on failure.
728 *
729 * Performs static frame buffer allocation. Opens the DRM device and add maps
730 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
731 * information. Creates a \e server context to grab the lock for the
732 * initialization ioctls and calls the other initilization functions in this
733 * file. Starts the CP engine via the DRM_RADEON_CP_START command.
734 *
735 * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
736 * initialization.
737 */
738 static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info )
739 {
740 RADEONDRIPtr pRADEONDRI;
741 int err;
742
743 usleep(100);
744 /*assert(!ctx->IsClient);*/
745
746 {
747 int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
748 int maxy = ctx->shared.fbSize / width_bytes;
749
750
751 if (maxy <= ctx->shared.virtualHeight * 3) {
752 fprintf(stderr,
753 "Static buffer allocation failed -- "
754 "need at least %d kB video memory (have %d kB)\n",
755 (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
756 ctx->cpp * 3 + 1023) / 1024,
757 ctx->shared.fbSize / 1024);
758 return 0;
759 }
760 }
761
762
763 if (info->ChipFamily >= CHIP_FAMILY_R300) {
764 fprintf(stderr,
765 "Direct rendering not yet supported on "
766 "Radeon 9700 and newer cards\n");
767 return 0;
768 }
769
770 info->registerSize = ctx->MMIOSize;
771 ctx->shared.SAREASize = DRM_PAGE_SIZE;
772
773 /* Note that drmOpen will try to load the kernel module, if needed. */
774 ctx->drmFD = drmOpen("radeon", NULL );
775 if (ctx->drmFD < 0) {
776 fprintf(stderr, "[drm] drmOpen failed\n");
777 return 0;
778 }
779
780 if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
781 fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
782 ctx->drmFD, ctx->pciBusID, strerror(-err));
783 return 0;
784 }
785
786 if (drmAddMap( ctx->drmFD,
787 0,
788 ctx->shared.SAREASize,
789 DRM_SHM,
790 DRM_CONTAINS_LOCK,
791 &ctx->shared.hSAREA) < 0)
792 {
793 fprintf(stderr, "[drm] drmAddMap failed\n");
794 return 0;
795 }
796 fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
797 ctx->shared.SAREASize, ctx->shared.hSAREA);
798
799 if (drmMap( ctx->drmFD,
800 ctx->shared.hSAREA,
801 ctx->shared.SAREASize,
802 (drmAddressPtr)(&ctx->pSAREA)) < 0)
803 {
804 fprintf(stderr, "[drm] drmMap failed\n");
805 return 0;
806 }
807 memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
808 fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
809 ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
810
811 /* Need to AddMap the framebuffer and mmio regions here:
812 */
813 if (drmAddMap( ctx->drmFD,
814 (drmHandle)ctx->FBStart,
815 ctx->FBSize,
816 DRM_FRAME_BUFFER,
817 #ifndef _EMBEDDED
818 0,
819 #else
820 DRM_READ_ONLY,
821 #endif
822 &ctx->shared.hFrameBuffer) < 0)
823 {
824 fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
825 return 0;
826 }
827
828 fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
829 ctx->shared.hFrameBuffer);
830
831
832
833 if (drmAddMap(ctx->drmFD,
834 ctx->MMIOStart,
835 ctx->MMIOSize,
836 DRM_REGISTERS,
837 DRM_READ_ONLY,
838 &info->registerHandle) < 0) {
839 fprintf(stderr, "[drm] drmAddMap mmio failed\n");
840 return 0;
841 }
842 fprintf(stderr,
843 "[drm] register handle = 0x%08lx\n", info->registerHandle);
844
845 /* Check the radeon DRM version */
846 if (!RADEONCheckDRMVersion(ctx, info)) {
847 return 0;
848 }
849
850 /* Initialize AGP */
851 if (!RADEONDRIAgpInit(ctx, info)) {
852 return 0;
853 }
854
855
856 /* Memory manager setup */
857 if (!RADEONMemoryInit(ctx, info)) {
858 return 0;
859 }
860
861 /* Create a 'server' context so we can grab the lock for
862 * initialization ioctls.
863 */
864 if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
865 fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
866 return 0;
867 }
868
869 DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
870
871 /* Initialize the kernel data structures */
872 if (!RADEONDRIKernelInit(ctx, info)) {
873 fprintf(stderr, "RADEONDRIKernelInit failed\n");
874 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
875 return 0;
876 }
877
878 /* Initialize the vertex buffers list */
879 if (!RADEONDRIBufInit(ctx, info)) {
880 fprintf(stderr, "RADEONDRIBufInit failed\n");
881 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
882 return 0;
883 }
884
885 /* Initialize IRQ */
886 RADEONDRIIrqInit(ctx, info);
887
888 /* Initialize kernel gart memory manager */
889 RADEONDRIAgpHeapInit(ctx, info);
890
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 = 1;
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 Establish the set of modes available for the display.
1032 *
1033 * \param ctx display handle.
1034 * \param numModes will receive the number of supported modes.
1035 * \param modes will point to the list of supported modes.
1036 *
1037 * \return one on success, or zero on failure.
1038 *
1039 * Allocates a single visual and fills it with information according to the
1040 * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
1041 * otherwise.
1042 */
1043 const __GLcontextModes __glModes[] = {
1044
1045 /* 32 bit, RGBA Depth=24 Stencil=8 */
1046 {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
1047 .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE,
1048 .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8,
1049 .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000,
1050 .rgbBits = 32, .indexBits = 0,
1051 .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
1052 .depthBits = 24, .stencilBits = 8,
1053 .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
1054
1055 /* 16 bit, RGB Depth=16 */
1056 {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
1057 .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE,
1058 .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0,
1059 .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0,
1060 .rgbBits = 16, .indexBits = 0,
1061 .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
1062 .depthBits = 16, .stencilBits = 0,
1063 .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
1064 };
1065 static int radeonInitContextModes( const DRIDriverContext *ctx,
1066 int *numModes, const __GLcontextModes **modes)
1067 {
1068 *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *);
1069 *modes = &__glModes[0];
1070 return 1;
1071 }
1072
1073
1074 /**
1075 * \brief Validate the fbdev mode.
1076 *
1077 * \param ctx display handle.
1078 *
1079 * \return one on success, or zero on failure.
1080 *
1081 * Saves some registers and returns 1.
1082 *
1083 * \sa radeonValidateMode().
1084 */
1085 static int radeonValidateMode( const DRIDriverContext *ctx )
1086 {
1087 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1088 RADEONInfoPtr info = ctx->driverPrivate;
1089
1090 info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
1091 info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
1092
1093 return 1;
1094 }
1095
1096
1097 /**
1098 * \brief Examine mode returned by fbdev.
1099 *
1100 * \param ctx display handle.
1101 *
1102 * \return one on success, or zero on failure.
1103 *
1104 * Restores registers that fbdev has clobbered and returns 1.
1105 *
1106 * \sa radeonValidateMode().
1107 */
1108 static int radeonPostValidateMode( const DRIDriverContext *ctx )
1109 {
1110 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1111 RADEONInfoPtr info = ctx->driverPrivate;
1112
1113 OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
1114 OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
1115
1116 return 1;
1117 }
1118
1119
1120 /**
1121 * \brief Initialize the framebuffer device mode
1122 *
1123 * \param ctx display handle.
1124 *
1125 * \return one on success, or zero on failure.
1126 *
1127 * Fills in \p info with some default values and some information from \p ctx
1128 * and then calls RADEONScreenInit() for the screen initialization.
1129 *
1130 * Before exiting clears the framebuffer memory accessing it directly.
1131 */
1132 static int radeonInitFBDev( DRIDriverContext *ctx )
1133 {
1134 RADEONInfoPtr info = calloc(1, sizeof(*info));
1135
1136 {
1137 int dummy = ctx->shared.virtualWidth;
1138
1139 switch (ctx->bpp / 8) {
1140 case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
1141 case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
1142 case 3:
1143 case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
1144 }
1145
1146 ctx->shared.virtualWidth = dummy;
1147 }
1148
1149 ctx->driverPrivate = (void *)info;
1150
1151 info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE;
1152 info->gartSize = RADEON_DEFAULT_AGP_SIZE;
1153 info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE;
1154 info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
1155 info->ringSize = RADEON_DEFAULT_RING_SIZE;
1156
1157 info->Chipset = ctx->chipset;
1158
1159 if (!get_chipfamily_from_chipset( info )) {
1160 fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n");
1161 fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n");
1162 return 0;
1163 }
1164
1165 info->frontPitch = ctx->shared.virtualWidth;
1166 info->LinearAddr = ctx->FBStart & 0xfc000000;
1167
1168
1169 if (!RADEONScreenInit( ctx, info ))
1170 return 0;
1171
1172
1173 return 1;
1174 }
1175
1176
1177 /**
1178 * \brief The screen is being closed, so clean up any state and free any
1179 * resources used by the DRI.
1180 *
1181 * \param ctx display handle.
1182 *
1183 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1184 * private data.
1185 */
1186 static void radeonHaltFBDev( DRIDriverContext *ctx )
1187 {
1188 drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
1189 drmClose(ctx->drmFD);
1190
1191 if (ctx->driverPrivate) {
1192 free(ctx->driverPrivate);
1193 ctx->driverPrivate = 0;
1194 }
1195 }
1196
1197
1198 extern void radeonNotifyFocus( int );
1199
1200 /**
1201 * \brief Exported driver interface for Mini GLX.
1202 *
1203 * \sa DRIDriverRec.
1204 */
1205 const struct DRIDriverRec __driDriver = {
1206 radeonInitContextModes,
1207 radeonValidateMode,
1208 radeonPostValidateMode,
1209 radeonInitFBDev,
1210 radeonHaltFBDev,
1211 RADEONEngineShutdown,
1212 RADEONEngineRestore,
1213 #ifndef _EMBEDDED
1214 0,
1215 #else
1216 radeonNotifyFocus,
1217 #endif
1218 };