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