~ubuntu-branches/ubuntu/trusty/xserver-xorg-video-mach64-lts-xenial/trusty-proposed

« back to all changes in this revision

Viewing changes to src/atidri.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2016-05-03 14:02:37 UTC
  • Revision ID: package-import@ubuntu.com-20160503140237-y946gbjc7p6fg9fn
Tags: upstream-6.9.5
ImportĀ upstreamĀ versionĀ 6.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; c-basic-offset: 3 -*- */
 
2
/*
 
3
 * Copyright 2000 Gareth Hughes
 
4
 * All Rights Reserved.
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the "Software"),
 
8
 * to deal in the Software without restriction, including without limitation
 
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
10
 * and/or sell copies of the Software, and to permit persons to whom the
 
11
 * Software is furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice (including the next
 
14
 * paragraph) shall be included in all copies or substantial portions of the
 
15
 * Software.
 
16
 *
 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
20
 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 
21
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 */
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#include "config.h"
 
27
#endif
 
28
/*
 
29
 * Authors:
 
30
 *   Gareth Hughes <gareth@valinux.com>
 
31
 *   Leif Delgass <ldelgass@retinalburn.net>
 
32
 */
 
33
 
 
34
#include <string.h>
 
35
#include <stdio.h>
 
36
#include <unistd.h>
 
37
 
 
38
/* Driver data structures */
 
39
#include "ati.h"
 
40
#include "atibus.h"
 
41
#include "atidri.h"
 
42
#include "atiregs.h"
 
43
#include "atistruct.h"
 
44
 
 
45
#include "atimach64io.h"
 
46
#include "atimach64version.h"
 
47
#include "mach64_dri.h"
 
48
#include "mach64_common.h"
 
49
#include "mach64_sarea.h"
 
50
 
 
51
/* X and server generic header files */
 
52
#include "xf86.h"
 
53
#include "windowstr.h"
 
54
 
 
55
/* GLX/DRI/DRM definitions */
 
56
#define _XF86DRI_SERVER_
 
57
#include "GL/glxtokens.h"
 
58
#include "sarea.h"
 
59
 
 
60
static char ATIKernelDriverName[] = "mach64";
 
61
static char ATIClientDriverName[] = "mach64";
 
62
 
 
63
/* Initialize the visual configs that are supported by the hardware.
 
64
 * These are combined with the visual configs that the indirect
 
65
 * rendering core supports, and the intersection is exported to the
 
66
 * client.
 
67
 */
 
68
static Bool ATIInitVisualConfigs( ScreenPtr pScreen )
 
69
{
 
70
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
71
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
72
   int numConfigs = 0;
 
73
   __GLXvisualConfig *pConfigs = NULL;
 
74
   ATIConfigPrivPtr pATIConfigs = NULL;
 
75
   ATIConfigPrivPtr *pATIConfigPtrs = NULL;
 
76
   int i, accum, stencil, db;
 
77
 
 
78
   switch ( pATI->bitsPerPixel ) {
 
79
   case 8:  /* 8bpp mode is not support */
 
80
   case 15: /* FIXME */
 
81
   case 24: /* FIXME */
 
82
      xf86DrvMsg(pScreen->myNum, X_ERROR,
 
83
                 "[dri] ATIInitVisualConfigs failed (%d bpp not supported).  "
 
84
                 "Disabling DRI.\n", pATI->bitsPerPixel);
 
85
      return FALSE;
 
86
 
 
87
#define ATI_USE_ACCUM   1
 
88
#define ATI_USE_STENCIL 1
 
89
 
 
90
   case 16:
 
91
 
 
92
      if ( pATI->depth != 16) {
 
93
         xf86DrvMsg(pScreen->myNum, X_ERROR,
 
94
                    "[dri] ATIInitVisualConfigs failed (depth %d at 16 bpp not supported).  "
 
95
                     "Disabling DRI.\n", pATI->depth);
 
96
         return FALSE;
 
97
      }
 
98
 
 
99
      numConfigs = 1;
 
100
      if ( ATI_USE_ACCUM )   numConfigs *= 2;
 
101
      if ( ATI_USE_STENCIL ) numConfigs *= 2;
 
102
      numConfigs *= 2; /* single- and double-buffered */
 
103
 
 
104
      pConfigs = (__GLXvisualConfig*)
 
105
         xnfcalloc( sizeof(__GLXvisualConfig), numConfigs );
 
106
      if ( !pConfigs ) {
 
107
         return FALSE;
 
108
      }
 
109
      pATIConfigs = (ATIConfigPrivPtr)
 
110
         xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs );
 
111
      if ( !pATIConfigs ) {
 
112
         free( pConfigs );
 
113
         return FALSE;
 
114
      }
 
115
      pATIConfigPtrs = (ATIConfigPrivPtr*)
 
116
         xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs );
 
117
      if ( !pATIConfigPtrs ) {
 
118
         free( pConfigs );
 
119
         free( pATIConfigs );
 
120
         return FALSE;
 
121
      }
 
122
 
 
123
      i = 0;
 
124
      for (db = 1; db >= 0; db--) {
 
125
         for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
 
126
            for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
 
127
               pATIConfigPtrs[i] = &pATIConfigs[i];
 
128
 
 
129
               pConfigs[i].vid                  = -1;
 
130
               pConfigs[i].class                = -1;
 
131
               pConfigs[i].rgba                 = TRUE;
 
132
               pConfigs[i].redSize              = 5;
 
133
               pConfigs[i].greenSize            = 6;
 
134
               pConfigs[i].blueSize             = 5;
 
135
               pConfigs[i].alphaSize            = 0;
 
136
               pConfigs[i].redMask              = 0x0000F800;
 
137
               pConfigs[i].greenMask            = 0x000007E0;
 
138
               pConfigs[i].blueMask             = 0x0000001F;
 
139
               pConfigs[i].alphaMask            = 0x00000000;
 
140
               if ( accum ) {   /* Simulated in software */
 
141
                  pConfigs[i].accumRedSize      = 16;
 
142
                  pConfigs[i].accumGreenSize    = 16;
 
143
                  pConfigs[i].accumBlueSize     = 16;
 
144
                  pConfigs[i].accumAlphaSize    = 0;
 
145
               } else {
 
146
                  pConfigs[i].accumRedSize      = 0;
 
147
                  pConfigs[i].accumGreenSize    = 0;
 
148
                  pConfigs[i].accumBlueSize     = 0;
 
149
                  pConfigs[i].accumAlphaSize    = 0;
 
150
               }
 
151
               pConfigs[i].doubleBuffer         = db ? TRUE : FALSE;
 
152
               pConfigs[i].stereo               = FALSE;
 
153
               pConfigs[i].bufferSize           = 16;
 
154
               pConfigs[i].depthSize            = 16;
 
155
               if ( stencil ) { /* Simulated in software */
 
156
                  pConfigs[i].stencilSize       = 8;
 
157
               } else {
 
158
                  pConfigs[i].stencilSize       = 0;
 
159
               }
 
160
               pConfigs[i].auxBuffers           = 0;
 
161
               pConfigs[i].level                = 0;
 
162
               if ( accum || stencil ) {
 
163
                  pConfigs[i].visualRating      = GLX_SLOW_CONFIG;
 
164
               } else {
 
165
                  pConfigs[i].visualRating      = GLX_NONE;
 
166
               }
 
167
               pConfigs[i].transparentPixel     = GLX_NONE;
 
168
               pConfigs[i].transparentRed       = 0;
 
169
               pConfigs[i].transparentGreen     = 0;
 
170
               pConfigs[i].transparentBlue      = 0;
 
171
               pConfigs[i].transparentAlpha     = 0;
 
172
               pConfigs[i].transparentIndex     = 0;
 
173
               i++;
 
174
            }
 
175
         }
 
176
      }
 
177
      break;
 
178
 
 
179
   case 32:
 
180
      numConfigs = 1;
 
181
      if ( ATI_USE_ACCUM )   numConfigs *= 2;
 
182
      if ( ATI_USE_STENCIL ) numConfigs *= 2;
 
183
      numConfigs *= 2; /* single- and double-buffered */
 
184
 
 
185
      pConfigs = (__GLXvisualConfig*)
 
186
         xnfcalloc( sizeof(__GLXvisualConfig), numConfigs );
 
187
      if ( !pConfigs ) {
 
188
         return FALSE;
 
189
      }
 
190
      pATIConfigs = (ATIConfigPrivPtr)
 
191
         xnfcalloc( sizeof(ATIConfigPrivRec), numConfigs );
 
192
      if ( !pATIConfigs ) {
 
193
         free( pConfigs );
 
194
         return FALSE;
 
195
      }
 
196
      pATIConfigPtrs = (ATIConfigPrivPtr*)
 
197
         xnfcalloc( sizeof(ATIConfigPrivPtr), numConfigs );
 
198
      if ( !pATIConfigPtrs ) {
 
199
         free( pConfigs );
 
200
         free( pATIConfigs );
 
201
         return FALSE;
 
202
      }
 
203
 
 
204
      i = 0;
 
205
      for (db = 1; db >= 0; db--) {
 
206
         for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
 
207
            for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
 
208
               pATIConfigPtrs[i] = &pATIConfigs[i];
 
209
 
 
210
               pConfigs[i].vid                  = -1;
 
211
               pConfigs[i].class                = -1;
 
212
               pConfigs[i].rgba                 = TRUE;
 
213
               pConfigs[i].redSize              = 8;
 
214
               pConfigs[i].greenSize            = 8;
 
215
               pConfigs[i].blueSize             = 8;
 
216
               pConfigs[i].alphaSize            = 0;
 
217
               pConfigs[i].redMask              = 0x00FF0000;
 
218
               pConfigs[i].greenMask            = 0x0000FF00;
 
219
               pConfigs[i].blueMask             = 0x000000FF;
 
220
               pConfigs[i].alphaMask            = 0x00000000;
 
221
               if ( accum ) {   /* Simulated in software */
 
222
                  pConfigs[i].accumRedSize      = 16;
 
223
                  pConfigs[i].accumGreenSize    = 16;
 
224
                  pConfigs[i].accumBlueSize     = 16;
 
225
                  pConfigs[i].accumAlphaSize    = 0;
 
226
               } else {
 
227
                  pConfigs[i].accumRedSize      = 0;
 
228
                  pConfigs[i].accumGreenSize    = 0;
 
229
                  pConfigs[i].accumBlueSize     = 0;
 
230
                  pConfigs[i].accumAlphaSize    = 0;
 
231
               }
 
232
               pConfigs[i].doubleBuffer         = db ? TRUE : FALSE;
 
233
               pConfigs[i].stereo               = FALSE;
 
234
               pConfigs[i].bufferSize           = 24;
 
235
               if ( stencil ) { /* Simulated in software */
 
236
                  pConfigs[i].depthSize         = 16;
 
237
                  pConfigs[i].stencilSize       = 8;
 
238
               } else {
 
239
                  pConfigs[i].depthSize         = 16;
 
240
                  pConfigs[i].stencilSize       = 0;
 
241
            }
 
242
               pConfigs[i].auxBuffers           = 0;
 
243
               pConfigs[i].level                = 0;
 
244
               if ( accum || stencil ) {
 
245
                  pConfigs[i].visualRating      = GLX_SLOW_CONFIG;
 
246
               } else {
 
247
                  pConfigs[i].visualRating      = GLX_NONE;
 
248
            }
 
249
               pConfigs[i].transparentPixel     = GLX_NONE;
 
250
               pConfigs[i].transparentRed       = 0;
 
251
               pConfigs[i].transparentGreen     = 0;
 
252
               pConfigs[i].transparentBlue      = 0;
 
253
               pConfigs[i].transparentAlpha     = 0;
 
254
               pConfigs[i].transparentIndex     = 0;
 
255
               i++;
 
256
            }
 
257
         }
 
258
      }
 
259
      break;
 
260
   }
 
261
 
 
262
   pATI->numVisualConfigs = numConfigs;
 
263
   pATI->pVisualConfigs = pConfigs;
 
264
   pATI->pVisualConfigsPriv = pATIConfigs;
 
265
   GlxSetVisualConfigs( numConfigs, pConfigs, (void**)pATIConfigPtrs );
 
266
   return TRUE;
 
267
}
 
268
 
 
269
/* Create the ATI-specific context information */
 
270
static Bool ATICreateContext( ScreenPtr pScreen, VisualPtr visual,
 
271
                              drm_context_t hwContext, void *pVisualConfigPriv,
 
272
                              DRIContextType contextStore )
 
273
{
 
274
   /* Nothing yet */
 
275
   return TRUE;
 
276
}
 
277
 
 
278
/* Destroy the ATI-specific context information */
 
279
static void ATIDestroyContext( ScreenPtr pScreen, drm_context_t hwContext,
 
280
                               DRIContextType contextStore )
 
281
{
 
282
   /* Nothing yet */
 
283
}
 
284
 
 
285
/* Called when the X server is woken up to allow the last client's
 
286
 * context to be saved and the X server's context to be loaded.
 
287
 * The client detects when it's context is not currently loaded and 
 
288
 * then loads it itself.  The X server's context is loaded in the
 
289
 * XAA Sync callback if NeedDRISync is set.
 
290
 */
 
291
static void ATIEnterServer( ScreenPtr pScreen )
 
292
{
 
293
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
294
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
295
 
 
296
   if ( pATI->directRenderingEnabled ) { 
 
297
      ATIDRIMarkSyncInt(pScreenInfo);
 
298
      ATIDRIMarkSyncExt(pScreenInfo);
 
299
   }
 
300
}
 
301
 
 
302
/* Called when the X server goes to sleep to allow the X server's
 
303
 * context to be saved and the last client's context to be loaded.
 
304
 * The client detects when it's context is not currently loaded and 
 
305
 * then loads it itself.  The X server keeps track of it's own state.
 
306
 */
 
307
static void ATILeaveServer( ScreenPtr pScreen )
 
308
{
 
309
   /* Nothing yet */
 
310
}
 
311
 
 
312
/* Contexts can be swapped by the X server if necessary.  This callback
 
313
 * is currently only used to perform any functions necessary when
 
314
 * entering or leaving the X server, and in the future might not be
 
315
 * necessary.
 
316
 */
 
317
static void ATIDRISwapContext( ScreenPtr pScreen,
 
318
                               DRISyncType syncType,
 
319
                               DRIContextType oldContextType,
 
320
                               void *oldContext,
 
321
                               DRIContextType newContextType,
 
322
                               void *newContext )
 
323
{
 
324
   if ( ( syncType == DRI_3D_SYNC ) && ( oldContextType == DRI_2D_CONTEXT ) &&
 
325
        ( newContextType == DRI_2D_CONTEXT ) ) {
 
326
      /* Entering from Wakeup */
 
327
      ATIEnterServer( pScreen );
 
328
   }
 
329
   if ( ( syncType == DRI_2D_SYNC ) && ( oldContextType == DRI_NO_CONTEXT ) &&
 
330
        ( newContextType == DRI_2D_CONTEXT ) ) {
 
331
      /* Exiting from Block Handler */
 
332
      ATILeaveServer( pScreen );
 
333
   }
 
334
}
 
335
 
 
336
#ifdef USE_XAA
 
337
static void ATIDRITransitionTo2d(ScreenPtr pScreen)
 
338
{
 
339
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
340
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
341
 
 
342
   if (pATI->backArea) {
 
343
      xf86FreeOffscreenArea(pATI->backArea);
 
344
      pATI->backArea = NULL;
 
345
   }
 
346
   if (pATI->depthTexArea) {
 
347
      xf86FreeOffscreenArea(pATI->depthTexArea);
 
348
      pATI->depthTexArea = NULL;
 
349
   }
 
350
   pATI->have3DWindows = FALSE;
 
351
}
 
352
 
 
353
static void ATIDRITransitionTo3d(ScreenPtr pScreen)
 
354
{
 
355
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
356
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
357
   FBAreaPtr fbArea;
 
358
   int width, height;
 
359
 
 
360
   xf86PurgeUnlockedOffscreenAreas(pScreen);
 
361
 
 
362
   xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0);
 
363
 
 
364
   xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
 
365
              "Largest offscreen area available: %d x %d\n",
 
366
              width, height);
 
367
 
 
368
   fbArea = xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
 
369
                                      height - pATI->depthTexLines - 
 
370
                                      pATI->backLines,
 
371
                                      pScreenInfo->displayWidth, NULL, NULL, NULL);
 
372
 
 
373
   if (!fbArea)
 
374
      xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder "
 
375
                 "offscreen area, you might experience screen corruption\n");
 
376
 
 
377
   if (!pATI->backArea) {
 
378
      pATI->backArea = 
 
379
         xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
 
380
                                   pATI->backLines,
 
381
                                   pScreenInfo->displayWidth,
 
382
                                   NULL, NULL, NULL);
 
383
   }
 
384
   if (!pATI->backArea)
 
385
      xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area "
 
386
                 "for back buffer, you might experience screen corruption\n");
 
387
 
 
388
   if (!pATI->depthTexArea) {
 
389
      pATI->depthTexArea = 
 
390
         xf86AllocateOffscreenArea(pScreen, pScreenInfo->displayWidth,
 
391
                                   pATI->depthTexLines,
 
392
                                   pScreenInfo->displayWidth,
 
393
                                   NULL, NULL, NULL);
 
394
   }
 
395
   if (!pATI->depthTexArea)
 
396
      xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen area "
 
397
                 "for depth buffer and textures, you might experience screen corruption\n");
 
398
 
 
399
   if (fbArea)
 
400
      xf86FreeOffscreenArea(fbArea);
 
401
 
 
402
   pATI->have3DWindows = TRUE;
 
403
}
 
404
#endif /* USE_XAA */
 
405
 
 
406
#ifdef USE_EXA
 
407
static void ATIDRITransitionTo2d_EXA(ScreenPtr pScreen)
 
408
{
 
409
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
410
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
411
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
412
 
 
413
   exaEnableDisableFBAccess(SCREEN_ARG(pScreen), FALSE);
 
414
 
 
415
   pATI->pExa->offScreenBase = pATIDRIServer->backOffset;
 
416
 
 
417
   exaEnableDisableFBAccess(SCREEN_ARG(pScreen), TRUE);
 
418
 
 
419
   pATI->have3DWindows = FALSE;
 
420
}
 
421
 
 
422
static void ATIDRITransitionTo3d_EXA(ScreenPtr pScreen)
 
423
{
 
424
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
425
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
426
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
427
 
 
428
   exaEnableDisableFBAccess(SCREEN_ARG(pScreen), FALSE);
 
429
 
 
430
   pATI->pExa->offScreenBase = pATIDRIServer->textureOffset +
 
431
                               pATIDRIServer->textureSize;
 
432
 
 
433
   exaEnableDisableFBAccess(SCREEN_ARG(pScreen), TRUE);
 
434
 
 
435
   pATI->have3DWindows = TRUE;
 
436
}
 
437
#endif /* USE_EXA */
 
438
 
 
439
/* Initialize the state of the back and depth buffers. */
 
440
static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx )
 
441
{
 
442
#ifdef USE_XAA
 
443
   ScreenPtr   pScreen = pWin->drawable.pScreen;
 
444
   ScrnInfoPtr pScreenInfo   = xf86ScreenToScrn(pScreen);
 
445
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
446
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
447
   XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
 
448
   BoxPtr      pbox, pboxSave;
 
449
   int         nbox, nboxSave;
 
450
   int         depth;
 
451
 
 
452
   depth = 0x0000ffff;
 
453
 
 
454
   if (!pXAAInfo)
 
455
      return;
 
456
 
 
457
   if (!pXAAInfo->SetupForSolidFill)
 
458
      return;
 
459
   
 
460
   /* FIXME: Only initialize the back and depth buffers for contexts
 
461
      that request them */
 
462
 
 
463
   /* FIXME: Use drm clear? (see Radeon driver) */
 
464
 
 
465
   pboxSave = pbox = REGION_RECTS(prgn);
 
466
   nboxSave = nbox = REGION_NUM_RECTS(prgn);
 
467
 
 
468
   (*pXAAInfo->SetupForSolidFill)(pScreenInfo, 0, GXcopy, (CARD32)(-1));
 
469
   for (; nbox; nbox--, pbox++) {
 
470
      (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
 
471
                                              pbox->x1 + pATIDRIServer->fbX,
 
472
                                              pbox->y1 + pATIDRIServer->fbY,
 
473
                                              pbox->x2 - pbox->x1,
 
474
                                              pbox->y2 - pbox->y1);
 
475
      (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
 
476
                                              pbox->x1 + pATIDRIServer->backX,
 
477
                                              pbox->y1 + pATIDRIServer->backY,
 
478
                                              pbox->x2 - pbox->x1,
 
479
                                              pbox->y2 - pbox->y1);
 
480
   }
 
481
 
 
482
   pbox = pboxSave;
 
483
   nbox = nboxSave;
 
484
 
 
485
   (*pXAAInfo->SetupForSolidFill)(pScreenInfo, depth, GXcopy, (CARD32)(-1));
 
486
   for (; nbox; nbox--, pbox++)
 
487
      (*pXAAInfo->SubsequentSolidFillRect)(pScreenInfo,
 
488
                                              pbox->x1 + pATIDRIServer->depthX,
 
489
                                              pbox->y1 + pATIDRIServer->depthY,
 
490
                                              pbox->x2 - pbox->x1,
 
491
                                              pbox->y2 - pbox->y1);
 
492
 
 
493
   ATIDRIMarkSyncInt(pScreenInfo);
 
494
#endif
 
495
}
 
496
 
 
497
/* Copy the back and depth buffers when the X server moves a window.
 
498
 * 
 
499
 * Note: this function was copied from the Radeon driver...
 
500
 * 
 
501
 * This routine is a modified form of XAADoBitBlt with the calls to
 
502
 * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
 
503
 * instead of destination. My origin is upside down so the ydir cases
 
504
 * are reversed.
 
505
 */
 
506
static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg,
 
507
                               RegionPtr prgnSrc, CARD32 indx )
 
508
{
 
509
#ifdef USE_XAA
 
510
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
511
    ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
512
    ATIPtr pATI = ATIPTR(pScreenInfo);
 
513
    XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
 
514
 
 
515
    int backOffsetPitch =  (((pATI->pDRIServerInfo->backPitch/8) << 22) |
 
516
                                           (pATI->pDRIServerInfo->backOffset >> 3));
 
517
#if 0
 
518
    int depthOffsetPitch = (((pATI->pDRIServerInfo->depthPitch/8) << 22) |
 
519
                                           (pATI->pDRIServerInfo->depthOffset >> 3));
 
520
#endif
 
521
    BoxPtr        pboxTmp, pboxNext, pboxBase;
 
522
    DDXPointPtr   pptTmp;
 
523
    int           xdir, ydir;
 
524
 
 
525
    int           screenwidth = pScreenInfo->virtualX;
 
526
    int           screenheight = pScreenInfo->virtualY;
 
527
 
 
528
    BoxPtr        pbox     = REGION_RECTS(prgnSrc);
 
529
    int           nbox     = REGION_NUM_RECTS(prgnSrc);
 
530
 
 
531
    BoxPtr        pboxNew1 = NULL;
 
532
    BoxPtr        pboxNew2 = NULL;
 
533
    DDXPointPtr   pptNew1  = NULL;
 
534
    DDXPointPtr   pptNew2  = NULL;
 
535
    DDXPointPtr   pptSrc   = &ptOldOrg;
 
536
 
 
537
    int           dx       = pWin->drawable.x - ptOldOrg.x;
 
538
    int           dy       = pWin->drawable.y - ptOldOrg.y;
 
539
 
 
540
   if (!pXAAInfo)
 
541
      return;
 
542
 
 
543
   if (!pXAAInfo->SetupForScreenToScreenCopy)
 
544
      return;
 
545
 
 
546
    /* FIXME: Only move the back and depth buffers for contexts
 
547
     * that request them.
 
548
     */
 
549
 
 
550
    /* If the copy will overlap in Y, reverse the order */
 
551
    if (dy > 0) {
 
552
        ydir = -1;
 
553
 
 
554
        if (nbox > 1) {
 
555
            /* Keep ordering in each band, reverse order of bands */
 
556
            pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec)*nbox);
 
557
            if (!pboxNew1) return;
 
558
            pptNew1 = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox);
 
559
            if (!pptNew1) {
 
560
                free(pboxNew1);
 
561
                return;
 
562
            }
 
563
            pboxBase = pboxNext = pbox+nbox-1;
 
564
            while (pboxBase >= pbox) {
 
565
                while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
 
566
                    pboxNext--;
 
567
                pboxTmp = pboxNext+1;
 
568
                pptTmp  = pptSrc + (pboxTmp - pbox);
 
569
                while (pboxTmp <= pboxBase) {
 
570
                    *pboxNew1++ = *pboxTmp++;
 
571
                    *pptNew1++  = *pptTmp++;
 
572
                }
 
573
                pboxBase = pboxNext;
 
574
            }
 
575
            pboxNew1 -= nbox;
 
576
            pbox      = pboxNew1;
 
577
            pptNew1  -= nbox;
 
578
            pptSrc    = pptNew1;
 
579
        }
 
580
    } else {
 
581
        /* No changes required */
 
582
        ydir = 1;
 
583
    }
 
584
 
 
585
    /* If the regions will overlap in X, reverse the order */
 
586
    if (dx > 0) {
 
587
        xdir = -1;
 
588
 
 
589
        if (nbox > 1) {
 
590
            /* reverse order of rects in each band */
 
591
            pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec)*nbox);
 
592
            pptNew2  = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox);
 
593
            if (!pboxNew2 || !pptNew2) {
 
594
                free(pptNew2);
 
595
                free(pboxNew2);
 
596
                free(pptNew1);
 
597
                free(pboxNew1);
 
598
                return;
 
599
            }
 
600
            pboxBase = pboxNext = pbox;
 
601
            while (pboxBase < pbox+nbox) {
 
602
                while ((pboxNext < pbox+nbox)
 
603
                       && (pboxNext->y1 == pboxBase->y1))
 
604
                    pboxNext++;
 
605
                pboxTmp = pboxNext;
 
606
                pptTmp  = pptSrc + (pboxTmp - pbox);
 
607
                while (pboxTmp != pboxBase) {
 
608
                    *pboxNew2++ = *--pboxTmp;
 
609
                    *pptNew2++  = *--pptTmp;
 
610
                }
 
611
                pboxBase = pboxNext;
 
612
            }
 
613
            pboxNew2 -= nbox;
 
614
            pbox      = pboxNew2;
 
615
            pptNew2  -= nbox;
 
616
            pptSrc    = pptNew2;
 
617
        }
 
618
    } else {
 
619
        /* No changes are needed */
 
620
        xdir = 1;
 
621
    }
 
622
 
 
623
    (*pXAAInfo->SetupForScreenToScreenCopy)(pScreenInfo, xdir, ydir, GXcopy,
 
624
                                               (CARD32)(-1), -1);
 
625
 
 
626
    for (; nbox-- ; pbox++) {
 
627
        int xa    = pbox->x1;
 
628
        int ya    = pbox->y1;
 
629
        int destx = xa + dx;
 
630
        int desty = ya + dy;
 
631
        int w     = pbox->x2 - xa + 1;
 
632
        int h     = pbox->y2 - ya + 1;
 
633
 
 
634
        if (destx < 0)                xa -= destx, w += destx, destx = 0;
 
635
        if (desty < 0)                ya -= desty, h += desty, desty = 0;
 
636
        if (destx + w > screenwidth)  w = screenwidth  - destx;
 
637
        if (desty + h > screenheight) h = screenheight - desty;
 
638
 
 
639
        if (w <= 0) continue;
 
640
        if (h <= 0) continue;
 
641
 
 
642
        ATIMach64WaitForFIFO(pATI, 2);
 
643
        outf(SRC_OFF_PITCH, backOffsetPitch);
 
644
        outf(DST_OFF_PITCH, backOffsetPitch);
 
645
 
 
646
        (*pXAAInfo->SubsequentScreenToScreenCopy)(pScreenInfo,
 
647
                                                     xa, ya,
 
648
                                                     destx, desty,
 
649
                                                     w, h);
 
650
#if 0
 
651
        /* FIXME: Move depth buffers? */
 
652
        ATIMach64WaitForFIFO(pATI, 2);
 
653
        outf(SRC_OFF_PITCH, depthOffsetPitch);
 
654
        outf(DST_OFF_PITCH, depthOffsetPitch);
 
655
 
 
656
        if (pATI->depthMoves)
 
657
            ATIScreenToScreenCopyDepth(pScreenInfo,
 
658
                                          xa, ya,
 
659
                                          destx, desty,
 
660
                                          w, h);
 
661
#endif
 
662
    }
 
663
 
 
664
    ATIMach64WaitForFIFO(pATI, 2);
 
665
    outf(SRC_OFF_PITCH, pATI->NewHW.dst_off_pitch);
 
666
    outf(DST_OFF_PITCH, pATI->NewHW.src_off_pitch);
 
667
 
 
668
    free(pptNew2);
 
669
    free(pboxNew2);
 
670
    free(pptNew1);
 
671
    free(pboxNew1);
 
672
 
 
673
    ATIDRIMarkSyncInt(pScreenInfo);
 
674
#endif
 
675
}
 
676
 
 
677
/* Compute log base 2 of val. */
 
678
static int Mach64MinBits(int val)
 
679
{
 
680
    int bits;
 
681
 
 
682
    if (!val) return 1;
 
683
    for (bits = 0; val; val >>= 1, ++bits);
 
684
    return bits;
 
685
}
 
686
 
 
687
static Bool ATIDRISetBufSize( ScreenPtr pScreen, unsigned int maxSize )
 
688
{
 
689
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
690
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
691
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
692
 
 
693
   if (pATI->OptionBufferSize) {
 
694
      if (pATI->OptionBufferSize < 1 || pATI->OptionBufferSize > maxSize  ) {
 
695
         xf86DrvMsg( pScreen->myNum, X_ERROR, "[drm] Illegal DMA buffers size: %d MB\n",
 
696
                     pATI->OptionBufferSize );
 
697
         return FALSE;
 
698
      }
 
699
      if (pATI->OptionBufferSize > 2) {
 
700
         xf86DrvMsg( pScreen->myNum, X_WARNING, "[drm] Illegal DMA buffers size: %d MB\n",
 
701
                     pATI->OptionBufferSize );
 
702
         xf86DrvMsg( pScreen->myNum, X_WARNING, "[drm] Clamping DMA buffers size to 2 MB\n");
 
703
         pATIDRIServer->bufferSize = 2;
 
704
      } else {
 
705
         pATIDRIServer->bufferSize = pATI->OptionBufferSize;
 
706
         xf86DrvMsg( pScreen->myNum, X_CONFIG, "[drm] Using %d MB for DMA buffers\n",
 
707
                     pATIDRIServer->bufferSize );
 
708
      }
 
709
   } else {
 
710
      xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[drm] Using %d MB for DMA buffers\n",
 
711
                  pATIDRIServer->bufferSize );
 
712
   }
 
713
 
 
714
   return TRUE;
 
715
}
 
716
 
 
717
static Bool ATIDRISetAgpMode( ScreenPtr pScreen )
 
718
{
 
719
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
720
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
721
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
722
 
 
723
   unsigned long mode   = drmAgpGetMode( pATI->drmFD );        /* Default mode */
 
724
   unsigned int vendor = drmAgpVendorId( pATI->drmFD );
 
725
   unsigned int device = drmAgpDeviceId( pATI->drmFD );
 
726
 
 
727
   if (pATI->OptionAGPMode > 0 && pATI->OptionAGPMode <= ATI_AGP_MAX_MODE) {
 
728
      pATIDRIServer->agpMode = pATI->OptionAGPMode;
 
729
      xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using AGP %dx Mode\n", 
 
730
                  pATIDRIServer->agpMode );
 
731
   } else if (pATI->OptionAGPMode > 0) {
 
732
      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Illegal AGP Mode: %d\n", 
 
733
                  pATI->OptionAGPMode );
 
734
      return FALSE;
 
735
   } else {
 
736
      /* If no mode configured, use the default mode obtained from agpgart */
 
737
      if ( mode & AGP_MODE_2X ) {
 
738
         pATIDRIServer->agpMode = 2;
 
739
      } else if ( mode & AGP_MODE_1X ) {
 
740
         pATIDRIServer->agpMode = 1;
 
741
      }
 
742
      xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using AGP %dx Mode\n", 
 
743
                  pATIDRIServer->agpMode );
 
744
   }
 
745
 
 
746
   mode &= ~AGP_MODE_MASK;
 
747
   switch ( pATIDRIServer->agpMode ) {
 
748
   case 2:          mode |= AGP_MODE_2X;
 
749
   case 1: default: mode |= AGP_MODE_1X;
 
750
   }
 
751
 
 
752
   if (pATI->OptionAGPSize) {
 
753
      switch (pATI->OptionAGPSize) {
 
754
      case 128:
 
755
      case  64:
 
756
      case  32:
 
757
      case  16:
 
758
      case   8:
 
759
      case   4:
 
760
         pATIDRIServer->agpSize = pATI->OptionAGPSize;
 
761
         xf86DrvMsg( pScreen->myNum, X_CONFIG, "[agp] Using %d MB AGP aperture\n", 
 
762
                     pATIDRIServer->agpSize );
 
763
         break;
 
764
      default:
 
765
         xf86DrvMsg( pScreen->myNum, X_ERROR,
 
766
                     "[agp] Illegal aperture size %d MB\n", pATI->OptionAGPSize );
 
767
         return FALSE;
 
768
      }
 
769
   } else {
 
770
      xf86DrvMsg( pScreen->myNum, X_DEFAULT, "[agp] Using %d MB AGP aperture\n", 
 
771
                  pATIDRIServer->agpSize );
 
772
   }
 
773
 
 
774
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
775
               "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
 
776
               mode, vendor, device,
 
777
               PCI_DEV_VENDOR_ID(pATI->PCIInfo),
 
778
               PCI_DEV_DEVICE_ID(pATI->PCIInfo) );
 
779
 
 
780
   if ( drmAgpEnable( pATI->drmFD, mode ) < 0 ) {
 
781
      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" );
 
782
      drmAgpRelease( pATI->drmFD );
 
783
      return FALSE;
 
784
   }
 
785
 
 
786
   return TRUE;
 
787
}
 
788
 
 
789
/* Initialize the AGP state.  Request memory for use in AGP space, and
 
790
 * initialize the Rage Pro registers to point to that memory.
 
791
 */
 
792
static Bool ATIDRIAgpInit( ScreenPtr pScreen )
 
793
{
 
794
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
795
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
796
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
797
 
 
798
   int ret;
 
799
   unsigned long cntl;
 
800
   int s, l;
 
801
 
 
802
   pATIDRIServer->agpSize = ATI_DEFAULT_AGP_SIZE;
 
803
   pATIDRIServer->agpMode = ATI_DEFAULT_AGP_MODE;
 
804
   pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE;
 
805
   pATIDRIServer->ringSize = 16; /* 16 kB ring */
 
806
 
 
807
   if ( drmAgpAcquire( pATI->drmFD ) < 0 ) {
 
808
      xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP not available\n" );
 
809
      return FALSE;
 
810
   }
 
811
 
 
812
   if (!ATIDRISetAgpMode( pScreen ))
 
813
      return FALSE;
 
814
 
 
815
   pATIDRIServer->agpOffset = 0;
 
816
 
 
817
   ret = drmAgpAlloc( pATI->drmFD, pATIDRIServer->agpSize*1024*1024,
 
818
                      0, NULL, &pATIDRIServer->agpHandle );
 
819
   if ( ret < 0 ) {
 
820
      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret );
 
821
      drmAgpRelease( pATI->drmFD );
 
822
      return FALSE;
 
823
   }
 
824
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
825
               "[agp] %d kB allocated with handle 0x%08x\n",
 
826
               pATIDRIServer->agpSize*1024, pATIDRIServer->agpHandle );
 
827
 
 
828
   if ( drmAgpBind( pATI->drmFD, pATIDRIServer->agpHandle, pATIDRIServer->agpOffset) < 0 ) {
 
829
      xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind\n" );
 
830
      drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle );
 
831
      drmAgpRelease( pATI->drmFD );
 
832
      return FALSE;
 
833
   }
 
834
 
 
835
   xf86DrvMsg(pScreen->myNum, X_INFO,
 
836
              "[agp] Using %d kB for DMA descriptor ring\n", pATIDRIServer->ringSize);
 
837
 
 
838
   if ( !ATIDRISetBufSize( pScreen, pATIDRIServer->agpSize ) )
 
839
      return FALSE;
 
840
 
 
841
   pATIDRIServer->agpTexSize    = pATIDRIServer->agpSize - pATIDRIServer->bufferSize;
 
842
 
 
843
   /* Reserve space for the DMA descriptor ring */
 
844
   pATIDRIServer->ringStart   = pATIDRIServer->agpOffset;
 
845
   pATIDRIServer->ringMapSize = pATIDRIServer->ringSize*1024; /* ringSize is in kB */
 
846
 
 
847
   /* Reserve space for the vertex buffer */
 
848
   pATIDRIServer->bufferStart   = pATIDRIServer->ringStart + pATIDRIServer->ringMapSize;
 
849
   pATIDRIServer->bufferMapSize = pATIDRIServer->bufferSize*1024*1024;
 
850
    
 
851
   /* Reserve the rest for AGP textures */
 
852
   pATIDRIServer->agpTexStart = pATIDRIServer->bufferStart + pATIDRIServer->bufferMapSize;
 
853
   s = (pATIDRIServer->agpSize*1024*1024 - pATIDRIServer->agpTexStart);
 
854
   l = Mach64MinBits((s-1) / MACH64_NR_TEX_REGIONS);
 
855
   if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY;
 
856
   pATIDRIServer->agpTexMapSize   = (s >> l) << l;
 
857
   pATIDRIServer->log2AGPTexGran  = l;
 
858
 
 
859
   xf86DrvMsg(pScreen->myNum, X_INFO,
 
860
              "[agp] Using %d kB for AGP textures\n", pATIDRIServer->agpTexMapSize/1024);
 
861
 
 
862
   /* Map DMA descriptor ring */
 
863
   if ( drmAddMap( pATI->drmFD, pATIDRIServer->ringStart, pATIDRIServer->ringMapSize,
 
864
                   DRM_AGP, DRM_RESTRICTED, &pATIDRIServer->ringHandle ) < 0 ) {
 
865
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
866
                  "[agp] Could not add ring mapping\n" );
 
867
      return FALSE;
 
868
   }
 
869
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
870
               "[agp] ring handle = 0x%08x\n",
 
871
               pATIDRIServer->ringHandle );
 
872
 
 
873
   if ( drmMap( pATI->drmFD, pATIDRIServer->ringHandle,
 
874
                pATIDRIServer->ringMapSize, &pATIDRIServer->ringMap ) < 0 ) {
 
875
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
876
                  "[agp] Could not map ring\n" );
 
877
      return FALSE;
 
878
   }
 
879
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
880
               "[agp] Ring mapped at 0x%08lx\n",
 
881
               (unsigned long)pATIDRIServer->ringMap );
 
882
 
 
883
   /* Map vertex buffers */
 
884
   if ( drmAddMap( pATI->drmFD, pATIDRIServer->bufferStart, pATIDRIServer->bufferMapSize,
 
885
                   DRM_AGP, DRM_READ_ONLY, &pATIDRIServer->bufferHandle ) < 0 ) {
 
886
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
887
                  "[agp] Could not add vertex buffers mapping\n" );
 
888
      return FALSE;
 
889
   }
 
890
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
891
               "[agp] vertex buffers handle = 0x%08x\n",
 
892
               pATIDRIServer->bufferHandle );
 
893
 
 
894
   if ( drmMap( pATI->drmFD, pATIDRIServer->bufferHandle,
 
895
                pATIDRIServer->bufferMapSize, &pATIDRIServer->bufferMap ) < 0 ) {
 
896
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
897
                  "[agp] Could not map vertex buffers\n" );
 
898
      return FALSE;
 
899
   }
 
900
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
901
               "[agp] Vertex buffers mapped at 0x%08lx\n",
 
902
               (unsigned long)pATIDRIServer->bufferMap );
 
903
 
 
904
   /* Map AGP Textures */
 
905
   if (drmAddMap(pATI->drmFD, pATIDRIServer->agpTexStart, pATIDRIServer->agpTexMapSize,
 
906
                 DRM_AGP, 0, &pATIDRIServer->agpTexHandle) < 0) {
 
907
      xf86DrvMsg(pScreen->myNum, X_ERROR,
 
908
                 "[agp] Could not add AGP texture region mapping\n");
 
909
      return FALSE;
 
910
   }
 
911
   xf86DrvMsg(pScreen->myNum, X_INFO,
 
912
              "[agp] AGP texture region handle = 0x%08x\n",
 
913
              pATIDRIServer->agpTexHandle);
 
914
 
 
915
   if (drmMap(pATI->drmFD, pATIDRIServer->agpTexHandle, pATIDRIServer->agpTexMapSize,
 
916
              &pATIDRIServer->agpTexMap) < 0) {
 
917
      xf86DrvMsg(pScreen->myNum, X_ERROR,
 
918
                 "[agp] Could not map AGP texture region\n");
 
919
      return FALSE;
 
920
   }
 
921
   xf86DrvMsg(pScreen->myNum, X_INFO,
 
922
              "[agp] AGP Texture region mapped at 0x%08lx\n",
 
923
              (unsigned long)pATIDRIServer->agpTexMap);
 
924
 
 
925
   /* Initialize Mach64's AGP registers */
 
926
   cntl  = inm( AGP_CNTL );
 
927
   cntl &= ~AGP_APER_SIZE_MASK;
 
928
   switch ( pATIDRIServer->agpSize ) {
 
929
   case 256: cntl |= AGP_APER_SIZE_256MB; break;
 
930
   case 128: cntl |= AGP_APER_SIZE_128MB; break;
 
931
   case  64: cntl |= AGP_APER_SIZE_64MB;  break;
 
932
   case  32: cntl |= AGP_APER_SIZE_32MB;  break;
 
933
   case  16: cntl |= AGP_APER_SIZE_16MB;  break;
 
934
   case   8: cntl |= AGP_APER_SIZE_8MB;   break;
 
935
   case   4: cntl |= AGP_APER_SIZE_4MB;   break;
 
936
   default:
 
937
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
938
                  "[agp] Illegal aperture size %d kB\n",
 
939
                  pATIDRIServer->agpSize*1024 );
 
940
      return FALSE;
 
941
   }
 
942
 
 
943
   /* 1 = DATA comes in clock in which TRDY sampled (default) */
 
944
   /* 0 = DATA comes in clock after TRDY sampled */
 
945
   cntl |= AGP_TRDY_MODE;
 
946
 
 
947
   /* 1 = generate all reads as high priority */
 
948
   /* 0 = generate all reads as their default priority (default) */
 
949
   /* Setting this only works for me at AGP 1x mode (LLD) */
 
950
   if (pATIDRIServer->agpMode == 1) {
 
951
      cntl |= HIGH_PRIORITY_READ_EN;
 
952
   } else {
 
953
      cntl &= ~HIGH_PRIORITY_READ_EN;
 
954
   }
 
955
 
 
956
   outm( AGP_BASE, drmAgpBase(pATI->drmFD) );
 
957
   outm( AGP_CNTL, cntl );
 
958
 
 
959
   return TRUE;
 
960
}
 
961
 
 
962
static Bool ATIDRIPciInit( ScreenPtr pScreen )
 
963
{
 
964
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
965
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
966
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
967
 
 
968
   pATIDRIServer->bufferSize = ATI_DEFAULT_BUFFER_SIZE;
 
969
   pATIDRIServer->ringSize = 16; /* 16 kB ring */
 
970
 
 
971
   if ( !ATIDRISetBufSize( pScreen, (unsigned)(-1) ) )
 
972
      return FALSE;
 
973
 
 
974
   /* Set size of the DMA descriptor ring */
 
975
   pATIDRIServer->ringStart   = 0;
 
976
   pATIDRIServer->ringMapSize = pATIDRIServer->ringSize*1024; /* ringSize is in kB */
 
977
 
 
978
   /* Set size of the vertex buffer */
 
979
   pATIDRIServer->bufferStart   = 0;
 
980
   pATIDRIServer->bufferMapSize = pATIDRIServer->bufferSize*1024*1024;
 
981
 
 
982
   /* Map DMA descriptor ring */
 
983
   if ( drmAddMap( pATI->drmFD, 0, pATIDRIServer->ringMapSize,
 
984
                   DRM_CONSISTENT, DRM_RESTRICTED, &pATIDRIServer->ringHandle ) < 0 ) {
 
985
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
986
                  "[pci] Could not add ring mapping\n" );
 
987
      return FALSE;
 
988
   }
 
989
   xf86DrvMsg( pScreen->myNum, X_INFO, "[pci] ring handle = 0x%08x\n",
 
990
               pATIDRIServer->ringHandle );
 
991
 
 
992
   if ( drmMap( pATI->drmFD, pATIDRIServer->ringHandle,
 
993
                pATIDRIServer->ringMapSize, &pATIDRIServer->ringMap ) < 0 ) {
 
994
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
995
                  "[pci] Could not map ring\n" );
 
996
      return FALSE;
 
997
   }
 
998
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
999
               "[pci] Ring mapped at 0x%08lx\n",
 
1000
               (unsigned long)pATIDRIServer->ringMap );
 
1001
 
 
1002
   /* Disable AGP for ForcePCIMode */
 
1003
   if ( pATI->BusType != ATI_BUS_PCI ) {
 
1004
       outm( AGP_BASE, 0 );
 
1005
       outm( AGP_CNTL, 0 );
 
1006
   }
 
1007
 
 
1008
   return TRUE;
 
1009
}
 
1010
 
 
1011
/* Add a map for the MMIO registers that will be accessed by any
 
1012
 * DRI-based clients.
 
1013
 */
 
1014
static Bool ATIDRIMapInit( ScreenPtr pScreen )
 
1015
{
 
1016
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1017
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1018
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1019
 
 
1020
   pATIDRIServer->regsSize = getpagesize();
 
1021
   if ( drmAddMap( pATI->drmFD, pATI->Block1Base,
 
1022
                   pATIDRIServer->regsSize,
 
1023
                   DRM_REGISTERS, DRM_READ_ONLY,
 
1024
                   &pATIDRIServer->regsHandle ) < 0 ) {
 
1025
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1026
                  "[drm] failed to map registers\n" );
 
1027
      return FALSE;
 
1028
   }
 
1029
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
1030
               "[drm] register handle = 0x%08x\n",
 
1031
               pATIDRIServer->regsHandle );
 
1032
 
 
1033
   return TRUE;
 
1034
}
 
1035
 
 
1036
/* Initialize the kernel data structures. */
 
1037
static Bool ATIDRIKernelInit( ScreenPtr pScreen )
 
1038
{
 
1039
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1040
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1041
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1042
   drmMach64Init info;
 
1043
 
 
1044
   memset( &info, 0, sizeof(drmMach64Init) );
 
1045
 
 
1046
   info.func                    = DRM_MACH64_INIT_DMA;
 
1047
   info.sarea_priv_offset       = sizeof(XF86DRISAREARec);
 
1048
   info.is_pci                  = pATIDRIServer->IsPCI;
 
1049
   info.dma_mode                = pATI->OptionDMAMode;
 
1050
 
 
1051
   info.fb_bpp                  = pATI->bitsPerPixel;
 
1052
   info.front_offset            = pATIDRIServer->frontOffset;
 
1053
   info.front_pitch             = pATIDRIServer->frontPitch;
 
1054
   info.back_offset             = pATIDRIServer->backOffset;
 
1055
   info.back_pitch              = pATIDRIServer->backPitch;
 
1056
 
 
1057
   info.depth_bpp               = 16;
 
1058
   info.depth_offset            = pATIDRIServer->depthOffset;
 
1059
   info.depth_pitch             = pATIDRIServer->depthPitch;
 
1060
 
 
1061
   info.fb_offset               = pATI->LinearBase;
 
1062
   info.mmio_offset             = pATIDRIServer->regsHandle;
 
1063
   info.ring_offset             = pATIDRIServer->ringHandle;
 
1064
   info.buffers_offset          = pATIDRIServer->bufferHandle;
 
1065
   info.agp_textures_offset     = pATIDRIServer->agpTexHandle;
 
1066
 
 
1067
   if ( drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT, 
 
1068
                         &info, sizeof(drmMach64Init) ) < 0 ) {
 
1069
      return FALSE;
 
1070
   } else {
 
1071
      return TRUE;
 
1072
   }
 
1073
}
 
1074
 
 
1075
/* Add a map for the DMA buffers that will be accessed by any
 
1076
 * DRI-based clients.
 
1077
 */
 
1078
static Bool ATIDRIAddBuffers( ScreenPtr pScreen )
 
1079
{
 
1080
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1081
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1082
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1083
 
 
1084
   /* Initialize vertex buffers */
 
1085
   if ( pATIDRIServer->IsPCI ) {
 
1086
      pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD,
 
1087
                                              pATIDRIServer->bufferMapSize/MACH64_BUFFER_SIZE,
 
1088
                                              MACH64_BUFFER_SIZE,
 
1089
                                              DRM_PCI_BUFFER_RO,
 
1090
                                              0 );
 
1091
   } else {
 
1092
      pATIDRIServer->numBuffers = drmAddBufs( pATI->drmFD,
 
1093
                                              pATIDRIServer->bufferMapSize/MACH64_BUFFER_SIZE,
 
1094
                                              MACH64_BUFFER_SIZE,
 
1095
                                              DRM_AGP_BUFFER,
 
1096
                                              pATIDRIServer->bufferStart );
 
1097
   }
 
1098
   if ( pATIDRIServer->numBuffers <= 0 ) {
 
1099
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1100
                  "[drm] Could not create DMA buffers list\n" );
 
1101
      return FALSE;
 
1102
   }
 
1103
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
1104
               "[drm] Added %d %d byte DMA buffers\n",
 
1105
               pATIDRIServer->numBuffers, MACH64_BUFFER_SIZE );
 
1106
 
 
1107
    return TRUE;
 
1108
}
 
1109
 
 
1110
static Bool ATIDRIMapBuffers( ScreenPtr pScreen )
 
1111
{
 
1112
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1113
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1114
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1115
 
 
1116
   pATIDRIServer->drmBuffers = drmMapBufs( pATI->drmFD );
 
1117
   if ( !pATIDRIServer->drmBuffers ) {
 
1118
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1119
                  "[drm] Failed to map DMA buffers list\n" );
 
1120
      return FALSE;
 
1121
   }
 
1122
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
1123
               "[drm] Mapped %d DMA buffers at 0x%08lx\n",
 
1124
               pATIDRIServer->drmBuffers->count,
 
1125
               (unsigned long)pATIDRIServer->drmBuffers->list->address );
 
1126
 
 
1127
   return TRUE;
 
1128
}
 
1129
 
 
1130
static Bool ATIDRIIrqInit( ScreenPtr pScreen )
 
1131
{
 
1132
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1133
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1134
 
 
1135
   if ( pATI->irq <= 0 ) {
 
1136
      pATI->irq = drmGetInterruptFromBusID(pATI->drmFD,
 
1137
                                           PCI_CFG_BUS(pATI->PCIInfo),
 
1138
                                           PCI_CFG_DEV(pATI->PCIInfo),
 
1139
                                           PCI_CFG_FUNC(pATI->PCIInfo));
 
1140
      if ( pATI->irq <= 0 ) {
 
1141
         xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
 
1142
                    "[drm] Couldn't find IRQ for bus id %d:%d:%d\n",
 
1143
                    PCI_CFG_BUS(pATI->PCIInfo),
 
1144
                    PCI_CFG_DEV(pATI->PCIInfo),
 
1145
                    PCI_CFG_FUNC(pATI->PCIInfo));
 
1146
         pATI->irq = 0;
 
1147
      } else if ((drmCtlInstHandler(pATI->drmFD, pATI->irq)) != 0) {
 
1148
         xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
 
1149
                    "[drm] Failed to initialize interrupt handler with IRQ %d\n",
 
1150
                    pATI->irq);
 
1151
         pATI->irq = 0;
 
1152
      }
 
1153
 
 
1154
      if (pATI->irq)
 
1155
         xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
 
1156
                    "[drm] Installed interrupt handler, using IRQ %d\n",
 
1157
                    pATI->irq);
 
1158
      else {
 
1159
         xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
 
1160
                    "[drm] Falling back to irq-free operation\n");
 
1161
         return FALSE;
 
1162
      }
 
1163
   }
 
1164
 
 
1165
   return TRUE;
 
1166
 
 
1167
}
 
1168
 
 
1169
/* Initialize the screen-specific data structures for the DRI and the
 
1170
 * Rage Pro.  This is the main entry point to the device-specific
 
1171
 * initialization code.  It calls device-independent DRI functions to
 
1172
 * create the DRI data structures and initialize the DRI state.
 
1173
 */
 
1174
Bool ATIDRIScreenInit( ScreenPtr pScreen )
 
1175
{
 
1176
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1177
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1178
   DRIInfoPtr pDRIInfo;
 
1179
   ATIDRIPtr pATIDRI;
 
1180
   ATIDRIServerInfoPtr pATIDRIServer;
 
1181
   drmVersionPtr version;
 
1182
   int major, minor, patch;
 
1183
 
 
1184
   /* Check that the GLX, DRI, and DRM modules have been loaded by testing
 
1185
    * for known symbols in each module.
 
1186
    */
 
1187
   if ( !xf86LoaderCheckSymbol("GlxSetVisualConfigs") ) return FALSE;
 
1188
   if ( !xf86LoaderCheckSymbol("drmAvailable") ) return FALSE;
 
1189
   if ( !xf86LoaderCheckSymbol("DRIQueryVersion") ) {
 
1190
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1191
                  "[dri] ATIDRIScreenInit failed (libdri.a too old)\n" );
 
1192
      return FALSE;
 
1193
   }
 
1194
 
 
1195
   /* Check the DRI version */
 
1196
   DRIQueryVersion( &major, &minor, &patch );
 
1197
   if ( major != DRIINFO_MAJOR_VERSION || minor < 0 ) {
 
1198
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1199
                  "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
 
1200
                  "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
 
1201
                  "[dri] Disabling the DRI.\n",
 
1202
                  major, minor, patch,
 
1203
                  DRIINFO_MAJOR_VERSION, 0 );
 
1204
      return FALSE;
 
1205
   }
 
1206
 
 
1207
   switch ( pATI->bitsPerPixel ) {
 
1208
   case 8:
 
1209
      /* These modes are not supported (yet). */
 
1210
   case 15:
 
1211
   case 24:
 
1212
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1213
                  "[dri] Direct rendering only supported in 16 and 32 bpp modes\n");
 
1214
      return FALSE;
 
1215
 
 
1216
      /* Only 16 and 32 color depths are supported currently. */
 
1217
   case 16:
 
1218
      if ( pATI->depth != 16) {
 
1219
         xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1220
                  "[dri] Direct rendering not supported for depth %d at fbbpp 16.\n", pATI->depth );
 
1221
         return FALSE;
 
1222
      }
 
1223
      break;
 
1224
   case 32:
 
1225
      break;
 
1226
   }
 
1227
 
 
1228
   /* Create the DRI data structure, and fill it in before calling the
 
1229
    * DRIScreenInit().
 
1230
    */
 
1231
   pDRIInfo = DRICreateInfoRec();
 
1232
   if ( !pDRIInfo ) return FALSE;
 
1233
 
 
1234
   pATI->pDRIInfo = pDRIInfo;
 
1235
   pDRIInfo->drmDriverName = ATIKernelDriverName;
 
1236
   pDRIInfo->clientDriverName = ATIClientDriverName;
 
1237
   if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
 
1238
      pDRIInfo->busIdString = DRICreatePCIBusID(pATI->PCIInfo);
 
1239
   } else {
 
1240
      pDRIInfo->busIdString = malloc( 64 );
 
1241
      sprintf( pDRIInfo->busIdString,
 
1242
               "PCI:%d:%d:%d",
 
1243
               PCI_DEV_BUS(pATI->PCIInfo),
 
1244
               PCI_DEV_DEV(pATI->PCIInfo),
 
1245
               PCI_DEV_FUNC(pATI->PCIInfo) );
 
1246
   }
 
1247
   pDRIInfo->ddxDriverMajorVersion = MACH64_VERSION_MAJOR;
 
1248
   pDRIInfo->ddxDriverMinorVersion = MACH64_VERSION_MINOR;
 
1249
   pDRIInfo->ddxDriverPatchVersion = MACH64_VERSION_PATCH;
 
1250
   pDRIInfo->frameBufferPhysicalAddress = (void *)pATI->LinearBase;
 
1251
   pDRIInfo->frameBufferSize = pATI->LinearSize;
 
1252
   pDRIInfo->frameBufferStride = (pScreenInfo->displayWidth *
 
1253
                                  pATI->FBBytesPerPixel);
 
1254
   pDRIInfo->ddxDrawableTableEntry = ATI_MAX_DRAWABLES;
 
1255
 
 
1256
   if ( SAREA_MAX_DRAWABLES < ATI_MAX_DRAWABLES ) {
 
1257
      pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
 
1258
   } else {
 
1259
      pDRIInfo->maxDrawableTableEntry = ATI_MAX_DRAWABLES;
 
1260
   }
 
1261
 
 
1262
   /* For now the mapping works by using a fixed size defined
 
1263
    * in the SAREA header
 
1264
    */
 
1265
   if ( sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) > SAREA_MAX ) {
 
1266
      ErrorF( "[dri] Data does not fit in SAREA\n" );
 
1267
      return FALSE;
 
1268
   }
 
1269
   xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %u+%u: %u\n",
 
1270
               (unsigned)sizeof(XF86DRISAREARec),
 
1271
               (unsigned)sizeof(ATISAREAPrivRec),
 
1272
               (unsigned)(sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec)) );
 
1273
   pDRIInfo->SAREASize = SAREA_MAX;
 
1274
 
 
1275
   pATIDRI = (ATIDRIPtr) xnfcalloc( sizeof(ATIDRIRec), 1 );
 
1276
   if ( !pATIDRI ) {
 
1277
      DRIDestroyInfoRec( pATI->pDRIInfo );
 
1278
      pATI->pDRIInfo = NULL;
 
1279
      xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
 
1280
                  "[dri] Failed to allocate memory for private record\n" );
 
1281
      return FALSE;
 
1282
   }
 
1283
   pATIDRIServer = (ATIDRIServerInfoPtr)
 
1284
      xnfcalloc( sizeof(ATIDRIServerInfoRec), 1 );
 
1285
   if ( !pATIDRIServer ) {
 
1286
      free( pATIDRI );
 
1287
      DRIDestroyInfoRec( pATI->pDRIInfo );
 
1288
      pATI->pDRIInfo = NULL;
 
1289
      xf86DrvMsg( pScreenInfo->scrnIndex, X_ERROR,
 
1290
                  "[dri] Failed to allocate memory for private record\n" );
 
1291
      return FALSE;
 
1292
   }
 
1293
 
 
1294
   pATI->pDRIServerInfo = pATIDRIServer;
 
1295
 
 
1296
   pDRIInfo->devPrivate         = pATIDRI;
 
1297
   pDRIInfo->devPrivateSize     = sizeof(ATIDRIRec);
 
1298
   pDRIInfo->contextSize        = sizeof(ATIDRIContextRec);
 
1299
 
 
1300
   pDRIInfo->CreateContext      = ATICreateContext;
 
1301
   pDRIInfo->DestroyContext     = ATIDestroyContext;
 
1302
   pDRIInfo->SwapContext        = ATIDRISwapContext;
 
1303
   pDRIInfo->InitBuffers        = ATIDRIInitBuffers;
 
1304
   pDRIInfo->MoveBuffers        = ATIDRIMoveBuffers;
 
1305
#ifdef USE_XAA
 
1306
   if (!pATI->useEXA) {
 
1307
      pDRIInfo->TransitionTo2d  = ATIDRITransitionTo2d;
 
1308
      pDRIInfo->TransitionTo3d  = ATIDRITransitionTo3d;
 
1309
   }
 
1310
#endif /* USE_XAA */
 
1311
#ifdef USE_EXA
 
1312
   if (pATI->useEXA) {
 
1313
      pDRIInfo->TransitionTo2d  = ATIDRITransitionTo2d_EXA;
 
1314
      pDRIInfo->TransitionTo3d  = ATIDRITransitionTo3d_EXA;
 
1315
   }
 
1316
#endif /* USE_EXA */
 
1317
   pDRIInfo->bufferRequests     = DRI_ALL_WINDOWS;
 
1318
 
 
1319
   pDRIInfo->createDummyCtx     = TRUE;
 
1320
   pDRIInfo->createDummyCtxPriv = FALSE;
 
1321
 
 
1322
   pATI->have3DWindows = FALSE;
 
1323
 
 
1324
   if ( !DRIScreenInit( pScreen, pDRIInfo, &pATI->drmFD ) ) {
 
1325
      free( pATIDRIServer );
 
1326
      pATI->pDRIServerInfo = NULL;
 
1327
      free( pDRIInfo->devPrivate );
 
1328
      pDRIInfo->devPrivate = NULL;
 
1329
      DRIDestroyInfoRec( pDRIInfo );
 
1330
      pDRIInfo = NULL;
 
1331
      xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1332
                  "[dri] DRIScreenInit Failed\n" );
 
1333
      return FALSE;
 
1334
   }
 
1335
   
 
1336
   /* Check the DRM lib version.
 
1337
      drmGetLibVersion was not supported in version 1.0, so check for
 
1338
      symbol first to avoid possible crash or hang.
 
1339
   */
 
1340
   if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
 
1341
      version = drmGetLibVersion(pATI->drmFD);
 
1342
   } else {
 
1343
      /* drmlib version 1.0.0 didn't have the drmGetLibVersion
 
1344
         entry point.  Fake it by allocating a version record
 
1345
         via drmGetVersion and changing it to version 1.0.0
 
1346
      */
 
1347
      version = drmGetVersion(pATI->drmFD);
 
1348
      version->version_major      = 1;
 
1349
      version->version_minor      = 0;
 
1350
      version->version_patchlevel = 0;
 
1351
   }
 
1352
 
 
1353
   if (version) {
 
1354
      if (version->version_major != 1 ||
 
1355
          version->version_minor < 1) {
 
1356
         /* incompatible drm library version */
 
1357
         xf86DrvMsg(pScreen->myNum, X_ERROR,
 
1358
                    "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
 
1359
                    "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n"
 
1360
                    "[dri] Disabling DRI.\n",
 
1361
                    version->version_major,
 
1362
                    version->version_minor,
 
1363
                    version->version_patchlevel);
 
1364
         drmFreeVersion(version);
 
1365
         ATIDRICloseScreen(pScreen);
 
1366
         return FALSE;
 
1367
      }
 
1368
      drmFreeVersion(version);
 
1369
   }
 
1370
 
 
1371
   /* Check the mach64 DRM version */
 
1372
   version = drmGetVersion( pATI->drmFD );
 
1373
   if ( version ) {
 
1374
      if ( version->version_major != 2 ||
 
1375
           version->version_minor < 0 ) {
 
1376
         /* Incompatible DRM version */
 
1377
         xf86DrvMsg( pScreen->myNum, X_ERROR,
 
1378
                     "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
 
1379
                     "[dri] mach64.o kernel module version is %d.%d.%d, but version 2.x is needed (with 2.x >= 2.0).\n"
 
1380
                     "[dri] Disabling DRI.\n",
 
1381
                     version->version_major,
 
1382
                     version->version_minor,
 
1383
                     version->version_patchlevel );
 
1384
         drmFreeVersion( version );
 
1385
         ATIDRICloseScreen( pScreen );
 
1386
         return FALSE;
 
1387
      }
 
1388
      drmFreeVersion( version );
 
1389
   }
 
1390
 
 
1391
   switch ( pATI->OptionDMAMode ) {
 
1392
   case MACH64_MODE_DMA_ASYNC:
 
1393
      xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request asynchronous DMA mode\n");
 
1394
      break;
 
1395
   case MACH64_MODE_DMA_SYNC:
 
1396
      xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request synchronous DMA mode\n");
 
1397
      break;
 
1398
   case MACH64_MODE_MMIO:
 
1399
      xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Will request pseudo-DMA (MMIO) mode\n");
 
1400
      break;
 
1401
   default:
 
1402
      xf86DrvMsg(pScreen->myNum, X_WARNING, "[drm] Unknown DMA mode\n");
 
1403
   }
 
1404
 
 
1405
   pATIDRIServer->IsPCI = (pATI->BusType == ATI_BUS_PCI || pATI->OptionIsPCI) ? TRUE : FALSE;
 
1406
 
 
1407
   if ( pATI->BusType != ATI_BUS_PCI && pATI->OptionIsPCI ) {
 
1408
       xf86DrvMsg(pScreen->myNum, X_CONFIG, "[dri] Forcing PCI mode\n");
 
1409
   }
 
1410
 
 
1411
   /* Initialize AGP */
 
1412
   if ( !pATIDRIServer->IsPCI && !ATIDRIAgpInit( pScreen ) ) {
 
1413
      pATIDRIServer->IsPCI = TRUE;
 
1414
      xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] AGP failed to initialize -- falling back to PCI mode.\n" );
 
1415
      xf86DrvMsg( pScreen->myNum, X_WARNING, "[agp] Make sure you have the agpgart kernel module loaded.\n" );
 
1416
   }
 
1417
 
 
1418
   /* Initialize PCI */
 
1419
   if ( pATIDRIServer->IsPCI && !ATIDRIPciInit( pScreen ) ) {
 
1420
      ATIDRICloseScreen( pScreen );
 
1421
      return FALSE;
 
1422
   }
 
1423
 
 
1424
   if ( !ATIDRIMapInit( pScreen ) ) {
 
1425
      ATIDRICloseScreen( pScreen );
 
1426
      return FALSE;
 
1427
   }
 
1428
 
 
1429
   if ( !ATIInitVisualConfigs( pScreen ) ) {
 
1430
      ATIDRICloseScreen( pScreen );
 
1431
      return FALSE;
 
1432
   }
 
1433
   xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO,
 
1434
               "[dri] Visual configs initialized\n" );
 
1435
 
 
1436
   xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO,
 
1437
               "[dri] Block 0 base at 0x%08lx\n", pATI->Block0Base );
 
1438
 
 
1439
   return TRUE;
 
1440
}
 
1441
 
 
1442
/* Finish initializing the device-dependent DRI state, and call
 
1443
 * DRIFinishScreenInit() to complete the device-independent DRI
 
1444
 * initialization.
 
1445
 */
 
1446
Bool ATIDRIFinishScreenInit( ScreenPtr pScreen )
 
1447
{
 
1448
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1449
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1450
   ATISAREAPrivPtr pSAREAPriv;
 
1451
   ATIDRIPtr pATIDRI;
 
1452
   ATIDRIServerInfoPtr pATIDRIServer;
 
1453
 
 
1454
   pATI->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
 
1455
 
 
1456
   /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit
 
1457
    * because *DRIKernelInit requires that the hardware lock is held by
 
1458
    * the X server, and the first time the hardware lock is grabbed is
 
1459
    * in DRIFinishScreenInit.
 
1460
    */
 
1461
   if ( !DRIFinishScreenInit( pScreen ) ) {
 
1462
      ATIDRICloseScreen( pScreen );
 
1463
      return FALSE;
 
1464
   }
 
1465
 
 
1466
   /* Initialize the DMA buffer list */
 
1467
   /* Need to do this before ATIDRIKernelInit so we can init the freelist */
 
1468
   if ( !ATIDRIAddBuffers( pScreen ) ) {
 
1469
      ATIDRICloseScreen( pScreen );
 
1470
      return FALSE;
 
1471
   }
 
1472
 
 
1473
   /* Initialize the kernel data structures */
 
1474
   if ( !ATIDRIKernelInit( pScreen ) ) {
 
1475
      xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 
 
1476
                 "[drm] Failed to initialize the mach64.o kernel module\n");
 
1477
      xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 
 
1478
                 "[drm] Check the system log for more information.\n");
 
1479
      ATIDRICloseScreen( pScreen );
 
1480
      return FALSE;
 
1481
   }
 
1482
 
 
1483
   if ( !ATIDRIMapBuffers( pScreen ) ) {
 
1484
      ATIDRICloseScreen( pScreen );
 
1485
      return FALSE;
 
1486
   }
 
1487
 
 
1488
   /* Initialize IRQ */
 
1489
   ATIDRIIrqInit( pScreen );
 
1490
 
 
1491
   pSAREAPriv = (ATISAREAPrivPtr) DRIGetSAREAPrivate( pScreen );
 
1492
   memset( pSAREAPriv, 0, sizeof(*pSAREAPriv) );
 
1493
 
 
1494
   pATIDRI = (ATIDRIPtr)pATI->pDRIInfo->devPrivate;
 
1495
   pATIDRIServer = pATI->pDRIServerInfo;
 
1496
 
 
1497
   pATIDRI->width = pScreenInfo->virtualX;
 
1498
   pATIDRI->height = pScreenInfo->virtualY;
 
1499
   pATIDRI->mem = pScreenInfo->videoRam * 1024;
 
1500
   pATIDRI->cpp = pScreenInfo->bitsPerPixel / 8;
 
1501
 
 
1502
   pATIDRI->IsPCI = pATIDRIServer->IsPCI;
 
1503
   pATIDRI->AGPMode = pATIDRIServer->agpMode;
 
1504
 
 
1505
   pATIDRI->frontOffset = pATIDRIServer->frontOffset;
 
1506
   pATIDRI->frontPitch = pATIDRIServer->frontPitch;
 
1507
 
 
1508
   pATIDRI->backOffset = pATIDRIServer->backOffset;
 
1509
   pATIDRI->backPitch = pATIDRIServer->backPitch;
 
1510
 
 
1511
   pATIDRI->depthOffset = pATIDRIServer->depthOffset;
 
1512
   pATIDRI->depthPitch = pATIDRIServer->depthPitch;
 
1513
 
 
1514
   pATIDRI->textureOffset = pATIDRIServer->textureOffset;
 
1515
   pATIDRI->textureSize = pATIDRIServer->textureSize;
 
1516
   pATIDRI->logTextureGranularity = pATIDRIServer->logTextureGranularity;
 
1517
 
 
1518
   pATIDRI->regs = pATIDRIServer->regsHandle;
 
1519
   pATIDRI->regsSize = pATIDRIServer->regsSize;
 
1520
 
 
1521
   pATIDRI->agp = pATIDRIServer->agpTexHandle;
 
1522
   pATIDRI->agpSize = pATIDRIServer->agpTexMapSize;
 
1523
   pATIDRI->logAgpTextureGranularity = pATIDRIServer->log2AGPTexGran;
 
1524
   pATIDRI->agpTextureOffset = pATIDRIServer->agpTexStart;
 
1525
 
 
1526
   return TRUE;
 
1527
}
 
1528
 
 
1529
/*
 
1530
 * This function will attempt to get the Mach64 hardware back into shape
 
1531
 * after a resume from disc. Its an extract from ATIDRIAgpInit and ATIDRIFinishScreenInit
 
1532
 * This also calls a new ioctl in the mach64 DRM that in its turn is
 
1533
 * an extraction of the hardware-affecting bits from mach64_do_init_drm()
 
1534
 * (see atidrm.c)
 
1535
 * I am assuming here that pATI->pDRIServerInfo doesn't change
 
1536
 * elsewhere in incomaptible ways.
 
1537
 * How will this code react to resuming after a failed resumeor pci based dri ?
 
1538
 */
 
1539
void ATIDRIResume( ScreenPtr pScreen )
 
1540
{
 
1541
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1542
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1543
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1544
 
 
1545
   xf86DrvMsg( pScreen->myNum, X_INFO,
 
1546
                 "[RESUME] Attempting to re-init Mach64 hardware.\n");
 
1547
 
 
1548
   if (!pATIDRIServer->IsPCI) {
 
1549
      if (!ATIDRISetAgpMode(pScreen))
 
1550
      return;
 
1551
 
 
1552
      outm( AGP_BASE, drmAgpBase(pATI->drmFD) );
 
1553
   }
 
1554
}
 
1555
 
 
1556
/* The screen is being closed, so clean up any state and free any
 
1557
 * resources used by the DRI.
 
1558
 */
 
1559
void ATIDRICloseScreen( ScreenPtr pScreen )
 
1560
{
 
1561
   ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
 
1562
   ATIPtr pATI = ATIPTR(pScreenInfo);
 
1563
   ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
 
1564
   drmMach64Init info;
 
1565
 
 
1566
   /* Stop interrupt generation and handling if used */
 
1567
   if ( pATI->irq > 0 ) {
 
1568
      if ( drmCtlUninstHandler(pATI->drmFD) != 0 ) {
 
1569
         xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
 
1570
                    "[drm] Error uninstalling interrupt handler for IRQ %d\n", pATI->irq);
 
1571
      } else {
 
1572
         xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
 
1573
                    "[drm] Uninstalled interrupt handler for IRQ %d\n", pATI->irq);
 
1574
      }
 
1575
      pATI->irq = 0;
 
1576
   }
 
1577
 
 
1578
   /* De-allocate DMA buffers */
 
1579
   if ( pATIDRIServer->drmBuffers ) {
 
1580
      drmUnmapBufs( pATIDRIServer->drmBuffers );
 
1581
      pATIDRIServer->drmBuffers = NULL;
 
1582
   }
 
1583
 
 
1584
   /* De-allocate all kernel resources */
 
1585
   memset(&info, 0, sizeof(drmMach64Init));
 
1586
   info.func = DRM_MACH64_CLEANUP_DMA;
 
1587
   drmCommandWrite( pATI->drmFD, DRM_MACH64_INIT,
 
1588
                    &info, sizeof(drmMach64Init) );
 
1589
 
 
1590
   /* De-allocate all AGP resources */
 
1591
   if ( pATIDRIServer->agpTexMap ) {
 
1592
      drmUnmap( pATIDRIServer->agpTexMap, pATIDRIServer->agpTexMapSize );
 
1593
      pATIDRIServer->agpTexMap = NULL;
 
1594
   }
 
1595
   if ( pATIDRIServer->bufferMap ) {
 
1596
      drmUnmap( pATIDRIServer->bufferMap, pATIDRIServer->bufferMapSize );
 
1597
      pATIDRIServer->bufferMap = NULL;
 
1598
   }
 
1599
   if ( pATIDRIServer->ringMap ) {
 
1600
      drmUnmap( pATIDRIServer->ringMap, pATIDRIServer->ringMapSize );
 
1601
      pATIDRIServer->ringMap = NULL;
 
1602
   }
 
1603
   if ( pATIDRIServer->agpHandle ) {
 
1604
      drmAgpUnbind( pATI->drmFD, pATIDRIServer->agpHandle );
 
1605
      drmAgpFree( pATI->drmFD, pATIDRIServer->agpHandle );
 
1606
      pATIDRIServer->agpHandle = 0;
 
1607
      drmAgpRelease( pATI->drmFD );
 
1608
   }
 
1609
 
 
1610
   /* De-allocate all PCI resources */
 
1611
   if ( pATIDRIServer->IsPCI && pATIDRIServer->ringHandle ) {
 
1612
      drmRmMap( pATI->drmFD, pATIDRIServer->ringHandle );
 
1613
      pATIDRIServer->ringHandle = 0;
 
1614
   }
 
1615
 
 
1616
   /* De-allocate all DRI resources */
 
1617
   DRICloseScreen( pScreen );
 
1618
 
 
1619
   /* De-allocate all DRI data structures */
 
1620
   if ( pATI->pDRIInfo ) {
 
1621
      if ( pATI->pDRIInfo->devPrivate ) {
 
1622
         free( pATI->pDRIInfo->devPrivate );
 
1623
         pATI->pDRIInfo->devPrivate = NULL;
 
1624
      }
 
1625
      DRIDestroyInfoRec( pATI->pDRIInfo );
 
1626
      pATI->pDRIInfo = NULL;
 
1627
   }
 
1628
   if ( pATI->pDRIServerInfo ) {
 
1629
      free( pATI->pDRIServerInfo );
 
1630
      pATI->pDRIServerInfo = NULL;
 
1631
   }
 
1632
   if ( pATI->pVisualConfigs ) {
 
1633
      free( pATI->pVisualConfigs );
 
1634
      pATI->pVisualConfigs = NULL;
 
1635
   }
 
1636
   if ( pATI->pVisualConfigsPriv ) {
 
1637
      free( pATI->pVisualConfigsPriv );
 
1638
      pATI->pVisualConfigsPriv = NULL;
 
1639
   }
 
1640
}