OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [drm-4.0/] [r128_cce.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
2
 * Created: Wed Apr  5 19:24:19 2000 by kevin@precisioninsight.com
3
 *
4
 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
5
 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6
 * All Rights Reserved.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction, including without limitation
11
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * Software is furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice (including the next
16
 * paragraph) shall be included in all copies or substantial portions of the
17
 * Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
 * DEALINGS IN THE SOFTWARE.
26
 *
27
 * Authors:
28
 *   Gareth Hughes <gareth@valinux.com>
29
 *
30
 */
31
 
32
#define __NO_VERSION__
33
#include "drmP.h"
34
#include "r128_drv.h"
35
 
36
#include <linux/interrupt.h>    /* For task queue support */
37
#include <linux/delay.h>
38
 
39
 
40
/* FIXME: Temporary CCE packet buffer */
41
u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32)));
42
 
43
/* CCE microcode (from ATI) */
44
static u32 r128_cce_microcode[] = {
45
        0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0,
46
        1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
47
        599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
48
        11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
49
        262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
50
        1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
51
        30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
52
        1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
53
        15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
54
        12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
55
        46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
56
        459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
57
        18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
58
        15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
59
        268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
60
        15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
61
        1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
62
        3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
63
        1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
64
        15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
65
        180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
66
        114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
67
        33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
68
        1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
69
        14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
70
        1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
71
        198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
72
        114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
73
        1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
74
        1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
75
        16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
76
        174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
77
        33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
78
        33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
79
        409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
86
};
87
 
88
 
89
#define DO_REMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d))
90
 
91
#define DO_REMAPFREE(_m, _d)                                                   \
92
        do {                                                                \
93
                if ((_m)->handle && (_m)->size)                             \
94
                        drm_ioremapfree((_m)->handle, (_m)->size, (_d));    \
95
        } while (0)
96
 
97
#define DO_FIND_MAP(_m, _o)                                                 \
98
        do {                                                                \
99
                int _i;                                                     \
100
                for (_i = 0; _i < dev->map_count; _i++) {                   \
101
                        if (dev->maplist[_i]->offset == _o) {               \
102
                                _m = dev->maplist[_i];                      \
103
                                break;                                      \
104
                        }                                                   \
105
                }                                                           \
106
        } while (0)
107
 
108
 
109
int R128_READ_PLL(drm_device_t *dev, int addr)
110
{
111
        drm_r128_private_t *dev_priv = dev->dev_private;
112
 
113
        R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
114
        return R128_READ(R128_CLOCK_CNTL_DATA);
115
}
116
 
117
#if 0
118
static void r128_status( drm_r128_private_t *dev_priv )
119
{
120
        printk( "GUI_STAT           = 0x%08x\n",
121
                (unsigned int)R128_READ( R128_GUI_STAT ) );
122
        printk( "PM4_STAT           = 0x%08x\n",
123
                (unsigned int)R128_READ( R128_PM4_STAT ) );
124
        printk( "PM4_BUFFER_DL_WPTR = 0x%08x\n",
125
                (unsigned int)R128_READ( R128_PM4_BUFFER_DL_WPTR ) );
126
        printk( "PM4_BUFFER_DL_RPTR = 0x%08x\n",
127
                (unsigned int)R128_READ( R128_PM4_BUFFER_DL_RPTR ) );
128
        printk( "PM4_MICRO_CNTL     = 0x%08x\n",
129
                (unsigned int)R128_READ( R128_PM4_MICRO_CNTL ) );
130
        printk( "PM4_BUFFER_CNTL    = 0x%08x\n",
131
                (unsigned int)R128_READ( R128_PM4_BUFFER_CNTL ) );
132
}
133
#endif
134
 
135
 
136
/* ================================================================
137
 * Engine, FIFO control
138
 */
139
 
140
static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
141
{
142
        u32 tmp;
143
        int i;
144
 
145
        tmp = R128_READ( R128_PC_NGUI_CTLSTAT ) | R128_PC_FLUSH_ALL;
146
        R128_WRITE( R128_PC_NGUI_CTLSTAT, tmp );
147
 
148
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
149
                if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) {
150
                        return 0;
151
                }
152
                udelay( 1 );
153
        }
154
 
155
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
156
        return -EBUSY;
157
}
158
 
159
static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
160
{
161
        int i;
162
 
163
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
164
                int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK;
165
                if ( slots >= entries ) return 0;
166
                udelay( 1 );
167
        }
168
 
169
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
170
        return -EBUSY;
171
}
172
 
173
static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
174
{
175
        int i, ret;
176
 
177
        ret = r128_do_wait_for_fifo( dev_priv, 64 );
178
        if ( !ret ) return ret;
179
 
180
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
181
                if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
182
                        r128_do_pixcache_flush( dev_priv );
183
                        return 0;
184
                }
185
                udelay( 1 );
186
        }
187
 
188
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
189
        return -EBUSY;
190
}
191
 
192
 
193
/* ================================================================
194
 * CCE control, initialization
195
 */
196
 
197
/* Load the microcode for the CCE */
198
static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
199
{
200
        int i;
201
 
202
        r128_do_wait_for_idle( dev_priv );
203
 
204
        R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
205
        for ( i = 0 ; i < 256 ; i++ ) {
206
                R128_WRITE( R128_PM4_MICROCODE_DATAH,
207
                            r128_cce_microcode[i * 2] );
208
                R128_WRITE( R128_PM4_MICROCODE_DATAL,
209
                            r128_cce_microcode[i * 2 + 1] );
210
        }
211
}
212
 
213
/* Flush any pending commands to the CCE.  This should only be used just
214
 * prior to a wait for idle, as it informs the engine that the command
215
 * stream is ending.
216
 */
217
static void r128_do_cce_flush( drm_r128_private_t *dev_priv )
218
{
219
        u32 tmp;
220
 
221
        tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE;
222
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp );
223
}
224
 
225
/* Wait for the CCE to go idle.
226
 */
227
static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
228
{
229
        int i;
230
 
231
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
232
                if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
233
                        int pm4stat = R128_READ( R128_PM4_STAT );
234
                        if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
235
                               dev_priv->cce_fifo_size ) &&
236
                             !(pm4stat & (R128_PM4_BUSY |
237
                                          R128_PM4_GUI_ACTIVE)) ) {
238
                                return r128_do_pixcache_flush( dev_priv );
239
                        }
240
                }
241
                udelay( 1 );
242
        }
243
 
244
#if 0
245
        DRM_ERROR( "failed!\n" );
246
        r128_status( dev_priv );
247
#endif
248
        return -EBUSY;
249
}
250
 
251
/* Start the Concurrent Command Engine.
252
 */
253
static void r128_do_cce_start( drm_r128_private_t *dev_priv )
254
{
255
        r128_do_wait_for_idle( dev_priv );
256
 
257
        R128_WRITE( R128_PM4_BUFFER_CNTL,
258
                    dev_priv->cce_mode | dev_priv->ring.size_l2qw );
259
        R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */
260
        R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN );
261
 
262
        dev_priv->cce_running = 1;
263
}
264
 
265
/* Reset the Concurrent Command Engine.  This will not flush any pending
266
 * commangs, so you must wait for the CCE command stream to complete
267
 * before calling this routine.
268
 */
269
static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
270
{
271
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
272
        R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
273
        *dev_priv->ring.head = 0;
274
        dev_priv->ring.tail = 0;
275
}
276
 
277
/* Stop the Concurrent Command Engine.  This will not flush any pending
278
 * commangs, so you must flush the command stream and wait for the CCE
279
 * to go idle before calling this routine.
280
 */
281
static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
282
{
283
        R128_WRITE( R128_PM4_MICRO_CNTL, 0 );
284
        R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 );
285
 
286
        dev_priv->cce_running = 0;
287
}
288
 
289
/* Reset the engine.  This will stop the CCE if it is running.
290
 */
291
static int r128_do_engine_reset( drm_device_t *dev )
292
{
293
        drm_r128_private_t *dev_priv = dev->dev_private;
294
        u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
295
 
296
        r128_do_pixcache_flush( dev_priv );
297
 
298
        clock_cntl_index = R128_READ( R128_CLOCK_CNTL_INDEX );
299
        mclk_cntl = R128_READ_PLL( dev, R128_MCLK_CNTL );
300
 
301
        R128_WRITE_PLL( R128_MCLK_CNTL,
302
                        mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP );
303
 
304
        gen_reset_cntl = R128_READ( R128_GEN_RESET_CNTL );
305
 
306
        /* Taken from the sample code - do not change */
307
        R128_WRITE( R128_GEN_RESET_CNTL,
308
                    gen_reset_cntl | R128_SOFT_RESET_GUI );
309
        R128_READ( R128_GEN_RESET_CNTL );
310
        R128_WRITE( R128_GEN_RESET_CNTL,
311
                    gen_reset_cntl & ~R128_SOFT_RESET_GUI );
312
        R128_READ( R128_GEN_RESET_CNTL );
313
 
314
        R128_WRITE_PLL( R128_MCLK_CNTL, mclk_cntl );
315
        R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index );
316
        R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl );
317
 
318
        /* Reset the CCE ring */
319
        r128_do_cce_reset( dev_priv );
320
 
321
        /* The CCE is no longer running after an engine reset */
322
        dev_priv->cce_running = 0;
323
 
324
        /* Reset any pending vertex, indirect buffers */
325
        r128_freelist_reset( dev );
326
 
327
        return 0;
328
}
329
 
330
static void r128_cce_init_ring_buffer( drm_device_t *dev )
331
{
332
        drm_r128_private_t *dev_priv = dev->dev_private;
333
        u32 ring_start;
334
        u32 tmp;
335
 
336
        /* The manual (p. 2) says this address is in "VM space".  This
337
         * means it's an offset from the start of AGP space.
338
         */
339
        ring_start = dev_priv->cce_ring->offset - dev->agp->base;
340
        R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
341
 
342
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
343
        R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
344
 
345
        /* DL_RPTR_ADDR is a physical address in AGP space. */
346
        *dev_priv->ring.head = 0;
347
        R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
348
                    dev_priv->ring_rptr->offset );
349
 
350
        /* Set watermark control */
351
        R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
352
                    ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
353
                    | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
354
                    | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
355
                    | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) );
356
 
357
        /* Force read.  Why?  Because it's in the examples... */
358
        R128_READ( R128_PM4_BUFFER_ADDR );
359
 
360
        /* Turn on bus mastering */
361
        tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS;
362
        R128_WRITE( R128_BUS_CNTL, tmp );
363
}
364
 
365
static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
366
{
367
        drm_r128_private_t *dev_priv;
368
        int i;
369
 
370
        dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
371
        if ( dev_priv == NULL )
372
                return -ENOMEM;
373
        dev->dev_private = (void *)dev_priv;
374
 
375
        memset( dev_priv, 0, sizeof(drm_r128_private_t) );
376
 
377
        dev_priv->is_pci = init->is_pci;
378
 
379
        /* GH: We don't support PCI cards until PCI GART is implemented.
380
         * Fail here so we can remove all checks for PCI cards around
381
         * the CCE ring code.
382
         */
383
        if ( dev_priv->is_pci ) {
384
                drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
385
                dev->dev_private = NULL;
386
                return -EINVAL;
387
        }
388
 
389
        dev_priv->usec_timeout = init->usec_timeout;
390
        if ( dev_priv->usec_timeout < 1 ||
391
             dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
392
                drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
393
                dev->dev_private = NULL;
394
                return -EINVAL;
395
        }
396
 
397
        dev_priv->cce_mode = init->cce_mode;
398
        dev_priv->cce_secure = init->cce_secure;
399
 
400
        /* GH: Simple idle check.
401
         */
402
        atomic_set( &dev_priv->idle_count, 0 );
403
 
404
        /* We don't support anything other than bus-mastering ring mode,
405
         * but the ring can be in either AGP or PCI space for the ring
406
         * read pointer.
407
         */
408
        if ( ( init->cce_mode != R128_PM4_192BM ) &&
409
             ( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
410
             ( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
411
             ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
412
                drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
413
                dev->dev_private = NULL;
414
                return -EINVAL;
415
        }
416
 
417
        switch ( init->cce_mode ) {
418
        case R128_PM4_NONPM4:
419
                dev_priv->cce_fifo_size = 0;
420
                break;
421
        case R128_PM4_192PIO:
422
        case R128_PM4_192BM:
423
                dev_priv->cce_fifo_size = 192;
424
                break;
425
        case R128_PM4_128PIO_64INDBM:
426
        case R128_PM4_128BM_64INDBM:
427
                dev_priv->cce_fifo_size = 128;
428
                break;
429
        case R128_PM4_64PIO_128INDBM:
430
        case R128_PM4_64BM_128INDBM:
431
        case R128_PM4_64PIO_64VCBM_64INDBM:
432
        case R128_PM4_64BM_64VCBM_64INDBM:
433
        case R128_PM4_64PIO_64VCPIO_64INDPIO:
434
                dev_priv->cce_fifo_size = 64;
435
                break;
436
        }
437
 
438
        dev_priv->fb_bpp        = init->fb_bpp;
439
        dev_priv->front_offset  = init->front_offset;
440
        dev_priv->front_pitch   = init->front_pitch;
441
        dev_priv->back_offset   = init->back_offset;
442
        dev_priv->back_pitch    = init->back_pitch;
443
 
444
        dev_priv->depth_bpp     = init->depth_bpp;
445
        dev_priv->depth_offset  = init->depth_offset;
446
        dev_priv->depth_pitch   = init->depth_pitch;
447
        dev_priv->span_offset   = init->span_offset;
448
 
449
        dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) |
450
                                          (dev_priv->front_offset >> 5));
451
        dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch/8) << 21) |
452
                                         (dev_priv->back_offset >> 5));
453
        dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
454
                                          (dev_priv->depth_offset >> 5) |
455
                                          R128_DST_TILE);
456
        dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
457
                                         (dev_priv->span_offset >> 5));
458
 
459
        /* FIXME: We want multiple shared areas, including one shared
460
         * only by the X Server and kernel module.
461
         */
462
        for ( i = 0 ; i < dev->map_count ; i++ ) {
463
                if ( dev->maplist[i]->type == _DRM_SHM ) {
464
                        dev_priv->sarea = dev->maplist[i];
465
                        break;
466
                }
467
        }
468
 
469
        DO_FIND_MAP( dev_priv->fb, init->fb_offset );
470
        DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
471
        DO_FIND_MAP( dev_priv->cce_ring, init->ring_offset );
472
        DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
473
        DO_FIND_MAP( dev_priv->buffers, init->buffers_offset );
474
 
475
        if ( !dev_priv->is_pci ) {
476
                DO_FIND_MAP( dev_priv->agp_textures,
477
                             init->agp_textures_offset );
478
        }
479
 
480
        dev_priv->sarea_priv =
481
                (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
482
                                     init->sarea_priv_offset);
483
 
484
        DO_REMAP( dev_priv->cce_ring, dev );
485
        DO_REMAP( dev_priv->ring_rptr, dev );
486
        DO_REMAP( dev_priv->buffers, dev );
487
#if 0
488
        if ( !dev_priv->is_pci ) {
489
                DO_REMAP( dev_priv->agp_textures, dev );
490
        }
491
#endif
492
 
493
        dev_priv->ring.head = ((__volatile__ u32 *)
494
                               dev_priv->ring_rptr->handle);
495
 
496
        dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
497
        dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
498
                              + init->ring_size / sizeof(u32));
499
        dev_priv->ring.size = init->ring_size;
500
        dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
501
 
502
        dev_priv->ring.tail_mask =
503
                (dev_priv->ring.size / sizeof(u32)) - 1;
504
 
505
        dev_priv->sarea_priv->last_frame = 0;
506
        R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
507
 
508
        dev_priv->sarea_priv->last_dispatch = 0;
509
        R128_WRITE( R128_LAST_DISPATCH_REG,
510
                    dev_priv->sarea_priv->last_dispatch );
511
 
512
        r128_cce_init_ring_buffer( dev );
513
        r128_cce_load_microcode( dev_priv );
514
        r128_do_engine_reset( dev );
515
 
516
        return 0;
517
}
518
 
519
static int r128_do_cleanup_cce( drm_device_t *dev )
520
{
521
        if ( dev->dev_private ) {
522
                drm_r128_private_t *dev_priv = dev->dev_private;
523
 
524
                DO_REMAPFREE( dev_priv->cce_ring, dev );
525
                DO_REMAPFREE( dev_priv->ring_rptr, dev );
526
                DO_REMAPFREE( dev_priv->buffers, dev );
527
#if 0
528
                if ( !dev_priv->is_pci ) {
529
                        DO_REMAPFREE( dev_priv->agp_textures, dev );
530
                }
531
#endif
532
 
533
                drm_free( dev->dev_private, sizeof(drm_r128_private_t),
534
                          DRM_MEM_DRIVER );
535
                dev->dev_private = NULL;
536
        }
537
 
538
        return 0;
539
}
540
 
541
int r128_cce_init( struct inode *inode, struct file *filp,
542
                   unsigned int cmd, unsigned long arg )
543
{
544
        drm_file_t *priv = filp->private_data;
545
        drm_device_t *dev = priv->dev;
546
        drm_r128_init_t init;
547
 
548
        if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
549
                return -EFAULT;
550
 
551
        switch ( init.func ) {
552
        case R128_INIT_CCE:
553
                return r128_do_init_cce( dev, &init );
554
        case R128_CLEANUP_CCE:
555
                return r128_do_cleanup_cce( dev );
556
        }
557
 
558
        return -EINVAL;
559
}
560
 
561
int r128_cce_start( struct inode *inode, struct file *filp,
562
                    unsigned int cmd, unsigned long arg )
563
{
564
        drm_file_t *priv = filp->private_data;
565
        drm_device_t *dev = priv->dev;
566
        drm_r128_private_t *dev_priv = dev->dev_private;
567
        DRM_DEBUG( "%s\n", __FUNCTION__ );
568
 
569
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
570
             dev->lock.pid != current->pid ) {
571
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
572
                return -EINVAL;
573
        }
574
        if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
575
                DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
576
                return 0;
577
        }
578
 
579
        r128_do_cce_start( dev_priv );
580
 
581
        return 0;
582
}
583
 
584
/* Stop the CCE.  The engine must have been idled before calling this
585
 * routine.
586
 */
587
int r128_cce_stop( struct inode *inode, struct file *filp,
588
                   unsigned int cmd, unsigned long arg )
589
{
590
        drm_file_t *priv = filp->private_data;
591
        drm_device_t *dev = priv->dev;
592
        drm_r128_private_t *dev_priv = dev->dev_private;
593
        drm_r128_cce_stop_t stop;
594
        int ret;
595
        DRM_DEBUG( "%s\n", __FUNCTION__ );
596
 
597
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
598
             dev->lock.pid != current->pid ) {
599
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
600
                return -EINVAL;
601
        }
602
 
603
        if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) )
604
                return -EFAULT;
605
 
606
        /* Flush any pending CCE commands.  This ensures any outstanding
607
         * commands are exectuted by the engine before we turn it off.
608
         */
609
        if ( stop.flush ) {
610
                r128_do_cce_flush( dev_priv );
611
        }
612
 
613
        /* If we fail to make the engine go idle, we return an error
614
         * code so that the DRM ioctl wrapper can try again.
615
         */
616
        if ( stop.idle ) {
617
                ret = r128_do_cce_idle( dev_priv );
618
                if ( ret < 0 ) return ret;
619
        }
620
 
621
        /* Finally, we can turn off the CCE.  If the engine isn't idle,
622
         * we will get some dropped triangles as they won't be fully
623
         * rendered before the CCE is shut down.
624
         */
625
        r128_do_cce_stop( dev_priv );
626
 
627
        /* Reset the engine */
628
        r128_do_engine_reset( dev );
629
 
630
        return 0;
631
}
632
 
633
/* Just reset the CCE ring.  Called as part of an X Server engine reset.
634
 */
635
int r128_cce_reset( struct inode *inode, struct file *filp,
636
                    unsigned int cmd, unsigned long arg )
637
{
638
        drm_file_t *priv = filp->private_data;
639
        drm_device_t *dev = priv->dev;
640
        drm_r128_private_t *dev_priv = dev->dev_private;
641
        DRM_DEBUG( "%s\n", __FUNCTION__ );
642
 
643
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
644
             dev->lock.pid != current->pid ) {
645
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
646
                return -EINVAL;
647
        }
648
        if ( !dev_priv ) {
649
                DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
650
                return -EINVAL;
651
        }
652
 
653
        r128_do_cce_reset( dev_priv );
654
 
655
        /* The CCE is no longer running after an engine reset */
656
        dev_priv->cce_running = 0;
657
 
658
        return 0;
659
}
660
 
661
int r128_cce_idle( struct inode *inode, struct file *filp,
662
                   unsigned int cmd, unsigned long arg )
663
{
664
        drm_file_t *priv = filp->private_data;
665
        drm_device_t *dev = priv->dev;
666
        drm_r128_private_t *dev_priv = dev->dev_private;
667
        DRM_DEBUG( "%s\n", __FUNCTION__ );
668
 
669
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
670
             dev->lock.pid != current->pid ) {
671
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
672
                return -EINVAL;
673
        }
674
 
675
        if ( dev_priv->cce_running ) {
676
                r128_do_cce_flush( dev_priv );
677
        }
678
 
679
        return r128_do_cce_idle( dev_priv );
680
}
681
 
682
int r128_engine_reset( struct inode *inode, struct file *filp,
683
                       unsigned int cmd, unsigned long arg )
684
{
685
        drm_file_t *priv = filp->private_data;
686
        drm_device_t *dev = priv->dev;
687
        DRM_DEBUG( "%s\n", __FUNCTION__ );
688
 
689
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
690
             dev->lock.pid != current->pid ) {
691
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
692
                return -EINVAL;
693
        }
694
 
695
        return r128_do_engine_reset( dev );
696
}
697
 
698
 
699
/* ================================================================
700
 * Freelist management
701
 */
702
#define R128_BUFFER_USED        0xffffffff
703
#define R128_BUFFER_FREE        0
704
 
705
#if 0
706
static int r128_freelist_init( drm_device_t *dev )
707
{
708
        drm_device_dma_t *dma = dev->dma;
709
        drm_r128_private_t *dev_priv = dev->dev_private;
710
        drm_buf_t *buf;
711
        drm_r128_buf_priv_t *buf_priv;
712
        drm_r128_freelist_t *entry;
713
        int i;
714
 
715
        dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
716
                                    DRM_MEM_DRIVER );
717
        if ( dev_priv->head == NULL )
718
                return -ENOMEM;
719
 
720
        memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) );
721
        dev_priv->head->age = R128_BUFFER_USED;
722
 
723
        for ( i = 0 ; i < dma->buf_count ; i++ ) {
724
                buf = dma->buflist[i];
725
                buf_priv = buf->dev_private;
726
 
727
                entry = drm_alloc( sizeof(drm_r128_freelist_t),
728
                                   DRM_MEM_DRIVER );
729
                if ( !entry ) return -ENOMEM;
730
 
731
                entry->age = R128_BUFFER_FREE;
732
                entry->buf = buf;
733
                entry->prev = dev_priv->head;
734
                entry->next = dev_priv->head->next;
735
                if ( !entry->next )
736
                        dev_priv->tail = entry;
737
 
738
                buf_priv->discard = 0;
739
                buf_priv->dispatched = 0;
740
                buf_priv->list_entry = entry;
741
 
742
                dev_priv->head->next = entry;
743
 
744
                if ( dev_priv->head->next )
745
                        dev_priv->head->next->prev = entry;
746
        }
747
 
748
        return 0;
749
 
750
}
751
#endif
752
 
753
drm_buf_t *r128_freelist_get( drm_device_t *dev )
754
{
755
        drm_device_dma_t *dma = dev->dma;
756
        drm_r128_private_t *dev_priv = dev->dev_private;
757
        drm_r128_buf_priv_t *buf_priv;
758
        drm_buf_t *buf;
759
        int i, t;
760
 
761
        /* FIXME: Optimize -- use freelist code */
762
 
763
        for ( i = 0 ; i < dma->buf_count ; i++ ) {
764
                buf = dma->buflist[i];
765
                buf_priv = buf->dev_private;
766
                if ( buf->pid == 0 )
767
                        return buf;
768
        }
769
 
770
        for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
771
                u32 done_age = R128_READ( R128_LAST_DISPATCH_REG );
772
 
773
                for ( i = 0 ; i < dma->buf_count ; i++ ) {
774
                        buf = dma->buflist[i];
775
                        buf_priv = buf->dev_private;
776
                        if ( buf->pending && buf_priv->age <= done_age ) {
777
                                /* The buffer has been processed, so it
778
                                 * can now be used.
779
                                 */
780
                                buf->pending = 0;
781
                                return buf;
782
                        }
783
                }
784
                udelay( 1 );
785
        }
786
 
787
        DRM_ERROR( "returning NULL!\n" );
788
        return NULL;
789
}
790
 
791
void r128_freelist_reset( drm_device_t *dev )
792
{
793
        drm_device_dma_t *dma = dev->dma;
794
        int i;
795
 
796
        for ( i = 0 ; i < dma->buf_count ; i++ ) {
797
                drm_buf_t *buf = dma->buflist[i];
798
                drm_r128_buf_priv_t *buf_priv = buf->dev_private;
799
                buf_priv->age = 0;
800
        }
801
}
802
 
803
 
804
/* ================================================================
805
 * CCE packet submission
806
 */
807
 
808
int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
809
{
810
        drm_r128_ring_buffer_t *ring = &dev_priv->ring;
811
        int i;
812
 
813
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
814
                ring->space = *ring->head - ring->tail;
815
                if ( ring->space <= 0 )
816
                        ring->space += ring->size;
817
 
818
                if ( ring->space >= n )
819
                        return 0;
820
 
821
                udelay( 1 );
822
        }
823
 
824
        return -EBUSY;
825
}
826
 
827
void r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
828
{
829
        drm_r128_ring_buffer_t *ring = &dev_priv->ring;
830
 
831
        ring->space = *ring->head - ring->tail;
832
#if R128_PERFORMANCE_BOXES
833
        if ( ring->space == 0 )
834
                atomic_inc( &dev_priv->idle_count );
835
#endif
836
        if ( ring->space <= 0 )
837
                ring->space += ring->size;
838
}
839
 
840
#if 0
841
static int r128_verify_command( drm_r128_private_t *dev_priv,
842
                                u32 cmd, int *size )
843
{
844
        int writing = 1;
845
 
846
        *size = 0;
847
 
848
        switch ( cmd & R128_CCE_PACKET_MASK ) {
849
        case R128_CCE_PACKET0:
850
                if ( (cmd & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2) &&
851
                     (cmd & R128_CCE_PACKET0_REG_MASK) !=
852
                     (R128_PM4_VC_FPU_SETUP >> 2) ) {
853
                        writing = 0;
854
                }
855
                *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
856
                break;
857
 
858
        case R128_CCE_PACKET1:
859
                if ( (cmd & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2) &&
860
                     (cmd & R128_CCE_PACKET1_REG0_MASK) !=
861
                     (R128_PM4_VC_FPU_SETUP >> 2) ) {
862
                        writing = 0;
863
                }
864
                if ( (cmd & R128_CCE_PACKET1_REG1_MASK) <= (0x1004 << 9) &&
865
                     (cmd & R128_CCE_PACKET1_REG1_MASK) !=
866
                     (R128_PM4_VC_FPU_SETUP << 9) ) {
867
                        writing = 0;
868
                }
869
                *size = 3;
870
                break;
871
 
872
        case R128_CCE_PACKET2:
873
                break;
874
 
875
        case R128_CCE_PACKET3:
876
                *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
877
                break;
878
 
879
        }
880
 
881
        return writing;
882
}
883
 
884
static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
885
                                           u32 *commands, int *count )
886
{
887
#if 0
888
        int write = dev_priv->sarea_priv->ring_write;
889
        int *write_ptr = dev_priv->ring_start + write;
890
        int c = *count;
891
        u32 tmp = 0;
892
        int psize = 0;
893
        int writing = 1;
894
        int timeout;
895
 
896
        while ( c > 0 ) {
897
                tmp = *commands++;
898
                if ( !psize ) {
899
                        writing = r128_verify_command( dev_priv, tmp, &psize );
900
                }
901
                psize--;
902
 
903
                if ( writing ) {
904
                        write++;
905
                        *write_ptr++ = tmp;
906
                }
907
                if ( write >= dev_priv->ring_entries ) {
908
                        write = 0;
909
                        write_ptr = dev_priv->ring_start;
910
                }
911
                timeout = 0;
912
                while ( write == *dev_priv->ring_read_ptr ) {
913
                        R128_READ( R128_PM4_BUFFER_DL_RPTR );
914
                        if ( timeout++ >= dev_priv->usec_timeout )
915
                                return -EBUSY;
916
                        udelay( 1 );
917
                }
918
                c--;
919
        }
920
 
921
        if ( write < 32 ) {
922
                memcpy( dev_priv->ring_end,
923
                        dev_priv->ring_start,
924
                        write * sizeof(u32) );
925
        }
926
 
927
        /* Make sure WC cache has been flushed */
928
        r128_flush_write_combine();
929
 
930
        dev_priv->sarea_priv->ring_write = write;
931
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
932
 
933
        *count = 0;
934
#endif
935
        return 0;
936
}
937
 
938
static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
939
                                             u32 *commands, int *count )
940
{
941
#if 0
942
        int write = dev_priv->sarea_priv->ring_write;
943
        int *write_ptr = dev_priv->ring_start + write;
944
        int c = *count;
945
        int timeout;
946
 
947
        while ( c > 0 ) {
948
                write++;
949
                *write_ptr++ = *commands++;
950
                if ( write >= dev_priv->ring_entries ) {
951
                        write = 0;
952
                        write_ptr = dev_priv->ring_start;
953
                }
954
 
955
                timeout = 0;
956
                while ( write == *dev_priv->ring_read_ptr ) {
957
                        R128_READ( R128_PM4_BUFFER_DL_RPTR );
958
                        if ( timeout++ >= dev_priv->usec_timeout )
959
                                return -EBUSY;
960
                        udelay( 1 );
961
                }
962
                c--;
963
        }
964
 
965
        if ( write < 32 ) {
966
                memcpy( dev_priv->ring_end,
967
                        dev_priv->ring_start,
968
                        write * sizeof(u32) );
969
        }
970
 
971
        /* Make sure WC cache has been flushed */
972
        r128_flush_write_combine();
973
 
974
        dev_priv->sarea_priv->ring_write = write;
975
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
976
 
977
        *count = 0;
978
#endif
979
        return 0;
980
}
981
#endif
982
 
983
/* Internal packet submission routine.  This uses the insecure versions
984
 * of the packet submission functions, and thus should only be used for
985
 * packets generated inside the kernel module.
986
 */
987
int r128_do_submit_packet( drm_r128_private_t *dev_priv,
988
                           u32 *buffer, int count )
989
{
990
        int c = count;
991
        int ret = 0;
992
 
993
#if 0
994
        int left = 0;
995
 
996
        if ( c >= dev_priv->ring_entries ) {
997
                c = dev_priv->ring_entries - 1;
998
                left = count - c;
999
        }
1000
 
1001
        /* Since this is only used by the kernel we can use the
1002
         * insecure ring buffer submit packet routine.
1003
         */
1004
        ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
1005
        c += left;
1006
#endif
1007
 
1008
        return ( ret < 0 ) ? ret : c;
1009
}
1010
 
1011
/* External packet submission routine.  This uses the secure versions
1012
 * by default, and can thus submit packets received from user space.
1013
 */
1014
int r128_cce_packet( struct inode *inode, struct file *filp,
1015
                     unsigned int cmd, unsigned long arg )
1016
{
1017
        drm_file_t *priv = filp->private_data;
1018
        drm_device_t *dev = priv->dev;
1019
        drm_r128_private_t *dev_priv = dev->dev_private;
1020
        drm_r128_packet_t packet;
1021
        u32 *buffer;
1022
        int c;
1023
        int size;
1024
        int ret = 0;
1025
 
1026
#if 0
1027
        /* GH: Disable packet submission for now.
1028
         */
1029
        return -EINVAL;
1030
#endif
1031
 
1032
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1033
             dev->lock.pid != current->pid ) {
1034
                DRM_ERROR( "r128_submit_packet called without lock held\n" );
1035
                return -EINVAL;
1036
        }
1037
 
1038
        if ( copy_from_user( &packet, (drm_r128_packet_t *)arg,
1039
                             sizeof(packet) ) )
1040
                return -EFAULT;
1041
 
1042
#if 0
1043
        c = packet.count;
1044
        size = c * sizeof(*buffer);
1045
 
1046
        {
1047
                int left = 0;
1048
 
1049
                if ( c >= dev_priv->ring_entries ) {
1050
                        c = dev_priv->ring_entries - 1;
1051
                        size = c * sizeof(*buffer);
1052
                        left = packet.count - c;
1053
                }
1054
 
1055
                buffer = kmalloc( size, 0 );
1056
                if ( buffer == NULL)
1057
                        return -ENOMEM;
1058
                if ( copy_from_user( buffer, packet.buffer, size ) )
1059
                        return -EFAULT;
1060
 
1061
                if ( dev_priv->cce_secure ) {
1062
                        ret = r128_submit_packet_ring_secure( dev_priv,
1063
                                                              buffer, &c );
1064
                } else {
1065
                        ret = r128_submit_packet_ring_insecure( dev_priv,
1066
                                                                buffer, &c );
1067
                }
1068
                c += left;
1069
        }
1070
 
1071
        kfree( buffer );
1072
#else
1073
        c = 0;
1074
#endif
1075
 
1076
        packet.count = c;
1077
        if ( copy_to_user( (drm_r128_packet_t *)arg, &packet,
1078
                           sizeof(packet) ) )
1079
                return -EFAULT;
1080
 
1081
        if ( ret ) {
1082
                return ret;
1083
        } else if ( c > 0 ) {
1084
                return -EAGAIN;
1085
        }
1086
        return 0;
1087
}
1088
 
1089
#if 0
1090
static int r128_send_vertbufs( drm_device_t *dev, drm_r128_vertex_t *v )
1091
{
1092
        drm_device_dma_t    *dma      = dev->dma;
1093
        drm_r128_private_t  *dev_priv = dev->dev_private;
1094
        drm_r128_buf_priv_t *buf_priv;
1095
        drm_buf_t           *buf;
1096
        int                  i, ret;
1097
        RING_LOCALS;
1098
 
1099
        /* Make sure we have valid data */
1100
        for (i = 0; i < v->send_count; i++) {
1101
                int idx = v->send_indices[i];
1102
 
1103
                if (idx < 0 || idx >= dma->buf_count) {
1104
                        DRM_ERROR("Index %d (of %d max)\n",
1105
                                  idx, dma->buf_count - 1);
1106
                        return -EINVAL;
1107
                }
1108
                buf = dma->buflist[idx];
1109
                if (buf->pid != current->pid) {
1110
                        DRM_ERROR("Process %d using buffer owned by %d\n",
1111
                                  current->pid, buf->pid);
1112
                        return -EINVAL;
1113
                }
1114
                if (buf->pending) {
1115
                        DRM_ERROR("Sending pending buffer:"
1116
                                  " buffer %d, offset %d\n",
1117
                                  v->send_indices[i], i);
1118
                        return -EINVAL;
1119
                }
1120
        }
1121
 
1122
        /* Wait for idle, if we've wrapped to make sure that all pending
1123
           buffers have been processed */
1124
        if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
1125
                if ((ret = r128_do_cce_idle(dev)) < 0) return ret;
1126
                dev_priv->submit_age = 0;
1127
                r128_freelist_reset(dev);
1128
        }
1129
 
1130
        /* Make sure WC cache has been flushed (if in PIO mode) */
1131
        if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
1132
 
1133
        /* FIXME: Add support for sending vertex buffer to the CCE here
1134
           instead of in client code.  The v->prim holds the primitive
1135
           type that should be drawn.  Loop over the list buffers in
1136
           send_indices[] and submit a packet for each VB.
1137
 
1138
           This will require us to loop over the clip rects here as
1139
           well, which implies that we extend the kernel driver to allow
1140
           cliprects to be stored here.  Note that the cliprects could
1141
           possibly come from the X server instead of the client, but
1142
           this will require additional changes to the DRI to allow for
1143
           this optimization. */
1144
 
1145
        /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
1146
#if 0
1147
        cce_buffer[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
1148
        cce_buffer[1] = dev_priv->submit_age;
1149
 
1150
        if ((ret = r128_do_submit_packet(dev, cce_buffer, 2)) < 0) {
1151
                /* Until we add support for sending VBs to the CCE in
1152
                   this routine, we can recover from this error.  After
1153
                   we add that support, we won't be able to easily
1154
                   recover, so we will probably have to implement
1155
                   another mechanism for handling timeouts from packets
1156
                   submitted directly by the kernel. */
1157
                return ret;
1158
        }
1159
#else
1160
        BEGIN_RING( 2 );
1161
 
1162
        OUT_RING( CCE_PACKET0( R128_VB_AGE_REG, 0 ) );
1163
        OUT_RING( dev_priv->submit_age );
1164
 
1165
        ADVANCE_RING();
1166
#endif
1167
        /* Now that the submit packet request has succeeded, we can mark
1168
           the buffers as pending */
1169
        for (i = 0; i < v->send_count; i++) {
1170
                buf = dma->buflist[v->send_indices[i]];
1171
                buf->pending = 1;
1172
 
1173
                buf_priv      = buf->dev_private;
1174
                buf_priv->age = dev_priv->submit_age;
1175
        }
1176
 
1177
        dev_priv->submit_age++;
1178
 
1179
        return 0;
1180
}
1181
#endif
1182
 
1183
 
1184
 
1185
 
1186
static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
1187
{
1188
        int i;
1189
        drm_buf_t *buf;
1190
 
1191
        for ( i = d->granted_count ; i < d->request_count ; i++ ) {
1192
                buf = r128_freelist_get( dev );
1193
                if ( !buf ) return -EAGAIN;
1194
 
1195
                buf->pid = current->pid;
1196
 
1197
                if ( copy_to_user( &d->request_indices[i], &buf->idx,
1198
                                   sizeof(buf->idx) ) )
1199
                        return -EFAULT;
1200
                if ( copy_to_user( &d->request_sizes[i], &buf->total,
1201
                                   sizeof(buf->total) ) )
1202
                        return -EFAULT;
1203
 
1204
                d->granted_count++;
1205
        }
1206
        return 0;
1207
}
1208
 
1209
int r128_cce_buffers( struct inode *inode, struct file *filp,
1210
                      unsigned int cmd, unsigned long arg )
1211
{
1212
        drm_file_t *priv = filp->private_data;
1213
        drm_device_t *dev = priv->dev;
1214
        drm_device_dma_t *dma = dev->dma;
1215
        int ret = 0;
1216
        drm_dma_t d;
1217
 
1218
        if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
1219
                return -EFAULT;
1220
 
1221
        if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
1222
             dev->lock.pid != current->pid ) {
1223
                DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
1224
                return -EINVAL;
1225
        }
1226
 
1227
        /* Please don't send us buffers.
1228
         */
1229
        if ( d.send_count != 0 ) {
1230
                DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
1231
                           current->pid, d.send_count );
1232
                return -EINVAL;
1233
        }
1234
 
1235
        /* We'll send you buffers.
1236
         */
1237
        if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
1238
                DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
1239
                           current->pid, d.request_count, dma->buf_count );
1240
                return -EINVAL;
1241
        }
1242
 
1243
        d.granted_count = 0;
1244
 
1245
        if ( d.request_count ) {
1246
                ret = r128_cce_get_buffers( dev, &d );
1247
        }
1248
 
1249
        if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
1250
                return -EFAULT;
1251
 
1252
        return ret;
1253
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.