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