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