File: /usr/src/linux/drivers/char/drm/radeon_cp.c

1     /* radeon_cp.c -- CP support for Radeon -*- linux-c -*-
2      *
3      * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4      * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5      * All Rights Reserved.
6      *
7      * Permission is hereby granted, free of charge, to any person obtaining a
8      * copy of this software and associated documentation files (the "Software"),
9      * to deal in the Software without restriction, including without limitation
10      * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11      * and/or sell copies of the Software, and to permit persons to whom the
12      * Software is furnished to do so, subject to the following conditions:
13      *
14      * The above copyright notice and this permission notice (including the next
15      * paragraph) shall be included in all copies or substantial portions of the
16      * Software.
17      *
18      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19      * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20      * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21      * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22      * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23      * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24      * DEALINGS IN THE SOFTWARE.
25      *
26      * Authors:
27      *    Kevin E. Martin <martin@valinux.com>
28      *    Gareth Hughes <gareth@valinux.com>
29      */
30     
31     #define __NO_VERSION__
32     #include "radeon.h"
33     #include "drmP.h"
34     #include "radeon_drv.h"
35     
36     #include <linux/interrupt.h>	/* For task queue support */
37     #include <linux/delay.h>
38     
39     #define RADEON_FIFO_DEBUG	0
40     
41     #if defined(__alpha__)
42     # define PCIGART_ENABLED
43     #else
44     # undef PCIGART_ENABLED
45     #endif
46     
47     
48     /* CP microcode (from ATI) */
49     static u32 radeon_cp_microcode[][2] = {
50     	{ 0x21007000, 0000000000 },
51     	{ 0x20007000, 0000000000 },
52     	{ 0x000000b4, 0x00000004 },
53     	{ 0x000000b8, 0x00000004 },
54     	{ 0x6f5b4d4c, 0000000000 },
55     	{ 0x4c4c427f, 0000000000 },
56     	{ 0x5b568a92, 0000000000 },
57     	{ 0x4ca09c6d, 0000000000 },
58     	{ 0xad4c4c4c, 0000000000 },
59     	{ 0x4ce1af3d, 0000000000 },
60     	{ 0xd8afafaf, 0000000000 },
61     	{ 0xd64c4cdc, 0000000000 },
62     	{ 0x4cd10d10, 0000000000 },
63     	{ 0x000f0000, 0x00000016 },
64     	{ 0x362f242d, 0000000000 },
65     	{ 0x00000012, 0x00000004 },
66     	{ 0x000f0000, 0x00000016 },
67     	{ 0x362f282d, 0000000000 },
68     	{ 0x000380e7, 0x00000002 },
69     	{ 0x04002c97, 0x00000002 },
70     	{ 0x000f0001, 0x00000016 },
71     	{ 0x333a3730, 0000000000 },
72     	{ 0x000077ef, 0x00000002 },
73     	{ 0x00061000, 0x00000002 },
74     	{ 0x00000021, 0x0000001a },
75     	{ 0x00004000, 0x0000001e },
76     	{ 0x00061000, 0x00000002 },
77     	{ 0x00000021, 0x0000001a },
78     	{ 0x00004000, 0x0000001e },
79     	{ 0x00061000, 0x00000002 },
80     	{ 0x00000021, 0x0000001a },
81     	{ 0x00004000, 0x0000001e },
82     	{ 0x00000017, 0x00000004 },
83     	{ 0x0003802b, 0x00000002 },
84     	{ 0x040067e0, 0x00000002 },
85     	{ 0x00000017, 0x00000004 },
86     	{ 0x000077e0, 0x00000002 },
87     	{ 0x00065000, 0x00000002 },
88     	{ 0x000037e1, 0x00000002 },
89     	{ 0x040067e1, 0x00000006 },
90     	{ 0x000077e0, 0x00000002 },
91     	{ 0x000077e1, 0x00000002 },
92     	{ 0x000077e1, 0x00000006 },
93     	{ 0xffffffff, 0000000000 },
94     	{ 0x10000000, 0000000000 },
95     	{ 0x0003802b, 0x00000002 },
96     	{ 0x040067e0, 0x00000006 },
97     	{ 0x00007675, 0x00000002 },
98     	{ 0x00007676, 0x00000002 },
99     	{ 0x00007677, 0x00000002 },
100     	{ 0x00007678, 0x00000006 },
101     	{ 0x0003802c, 0x00000002 },
102     	{ 0x04002676, 0x00000002 },
103     	{ 0x00007677, 0x00000002 },
104     	{ 0x00007678, 0x00000006 },
105     	{ 0x0000002f, 0x00000018 },
106     	{ 0x0000002f, 0x00000018 },
107     	{ 0000000000, 0x00000006 },
108     	{ 0x00000030, 0x00000018 },
109     	{ 0x00000030, 0x00000018 },
110     	{ 0000000000, 0x00000006 },
111     	{ 0x01605000, 0x00000002 },
112     	{ 0x00065000, 0x00000002 },
113     	{ 0x00098000, 0x00000002 },
114     	{ 0x00061000, 0x00000002 },
115     	{ 0x64c0603e, 0x00000004 },
116     	{ 0x000380e6, 0x00000002 },
117     	{ 0x040025c5, 0x00000002 },
118     	{ 0x00080000, 0x00000016 },
119     	{ 0000000000, 0000000000 },
120     	{ 0x0400251d, 0x00000002 },
121     	{ 0x00007580, 0x00000002 },
122     	{ 0x00067581, 0x00000002 },
123     	{ 0x04002580, 0x00000002 },
124     	{ 0x00067581, 0x00000002 },
125     	{ 0x00000049, 0x00000004 },
126     	{ 0x00005000, 0000000000 },
127     	{ 0x000380e6, 0x00000002 },
128     	{ 0x040025c5, 0x00000002 },
129     	{ 0x00061000, 0x00000002 },
130     	{ 0x0000750e, 0x00000002 },
131     	{ 0x00019000, 0x00000002 },
132     	{ 0x00011055, 0x00000014 },
133     	{ 0x00000055, 0x00000012 },
134     	{ 0x0400250f, 0x00000002 },
135     	{ 0x0000504f, 0x00000004 },
136     	{ 0x000380e6, 0x00000002 },
137     	{ 0x040025c5, 0x00000002 },
138     	{ 0x00007565, 0x00000002 },
139     	{ 0x00007566, 0x00000002 },
140     	{ 0x00000058, 0x00000004 },
141     	{ 0x000380e6, 0x00000002 },
142     	{ 0x040025c5, 0x00000002 },
143     	{ 0x01e655b4, 0x00000002 },
144     	{ 0x4401b0e4, 0x00000002 },
145     	{ 0x01c110e4, 0x00000002 },
146     	{ 0x26667066, 0x00000018 },
147     	{ 0x040c2565, 0x00000002 },
148     	{ 0x00000066, 0x00000018 },
149     	{ 0x04002564, 0x00000002 },
150     	{ 0x00007566, 0x00000002 },
151     	{ 0x0000005d, 0x00000004 },
152     	{ 0x00401069, 0x00000008 },
153     	{ 0x00101000, 0x00000002 },
154     	{ 0x000d80ff, 0x00000002 },
155     	{ 0x0080006c, 0x00000008 },
156     	{ 0x000f9000, 0x00000002 },
157     	{ 0x000e00ff, 0x00000002 },
158     	{ 0000000000, 0x00000006 },
159     	{ 0x0000008f, 0x00000018 },
160     	{ 0x0000005b, 0x00000004 },
161     	{ 0x000380e6, 0x00000002 },
162     	{ 0x040025c5, 0x00000002 },
163     	{ 0x00007576, 0x00000002 },
164     	{ 0x00065000, 0x00000002 },
165     	{ 0x00009000, 0x00000002 },
166     	{ 0x00041000, 0x00000002 },
167     	{ 0x0c00350e, 0x00000002 },
168     	{ 0x00049000, 0x00000002 },
169     	{ 0x00051000, 0x00000002 },
170     	{ 0x01e785f8, 0x00000002 },
171     	{ 0x00200000, 0x00000002 },
172     	{ 0x0060007e, 0x0000000c },
173     	{ 0x00007563, 0x00000002 },
174     	{ 0x006075f0, 0x00000021 },
175     	{ 0x20007073, 0x00000004 },
176     	{ 0x00005073, 0x00000004 },
177     	{ 0x000380e6, 0x00000002 },
178     	{ 0x040025c5, 0x00000002 },
179     	{ 0x00007576, 0x00000002 },
180     	{ 0x00007577, 0x00000002 },
181     	{ 0x0000750e, 0x00000002 },
182     	{ 0x0000750f, 0x00000002 },
183     	{ 0x00a05000, 0x00000002 },
184     	{ 0x00600083, 0x0000000c },
185     	{ 0x006075f0, 0x00000021 },
186     	{ 0x000075f8, 0x00000002 },
187     	{ 0x00000083, 0x00000004 },
188     	{ 0x000a750e, 0x00000002 },
189     	{ 0x000380e6, 0x00000002 },
190     	{ 0x040025c5, 0x00000002 },
191     	{ 0x0020750f, 0x00000002 },
192     	{ 0x00600086, 0x00000004 },
193     	{ 0x00007570, 0x00000002 },
194     	{ 0x00007571, 0x00000002 },
195     	{ 0x00007572, 0x00000006 },
196     	{ 0x000380e6, 0x00000002 },
197     	{ 0x040025c5, 0x00000002 },
198     	{ 0x00005000, 0x00000002 },
199     	{ 0x00a05000, 0x00000002 },
200     	{ 0x00007568, 0x00000002 },
201     	{ 0x00061000, 0x00000002 },
202     	{ 0x00000095, 0x0000000c },
203     	{ 0x00058000, 0x00000002 },
204     	{ 0x0c607562, 0x00000002 },
205     	{ 0x00000097, 0x00000004 },
206     	{ 0x000380e6, 0x00000002 },
207     	{ 0x040025c5, 0x00000002 },
208     	{ 0x00600096, 0x00000004 },
209     	{ 0x400070e5, 0000000000 },
210     	{ 0x000380e6, 0x00000002 },
211     	{ 0x040025c5, 0x00000002 },
212     	{ 0x000380e5, 0x00000002 },
213     	{ 0x000000a8, 0x0000001c },
214     	{ 0x000650aa, 0x00000018 },
215     	{ 0x040025bb, 0x00000002 },
216     	{ 0x000610ab, 0x00000018 },
217     	{ 0x040075bc, 0000000000 },
218     	{ 0x000075bb, 0x00000002 },
219     	{ 0x000075bc, 0000000000 },
220     	{ 0x00090000, 0x00000006 },
221     	{ 0x00090000, 0x00000002 },
222     	{ 0x000d8002, 0x00000006 },
223     	{ 0x00007832, 0x00000002 },
224     	{ 0x00005000, 0x00000002 },
225     	{ 0x000380e7, 0x00000002 },
226     	{ 0x04002c97, 0x00000002 },
227     	{ 0x00007820, 0x00000002 },
228     	{ 0x00007821, 0x00000002 },
229     	{ 0x00007800, 0000000000 },
230     	{ 0x01200000, 0x00000002 },
231     	{ 0x20077000, 0x00000002 },
232     	{ 0x01200000, 0x00000002 },
233     	{ 0x20007000, 0x00000002 },
234     	{ 0x00061000, 0x00000002 },
235     	{ 0x0120751b, 0x00000002 },
236     	{ 0x8040750a, 0x00000002 },
237     	{ 0x8040750b, 0x00000002 },
238     	{ 0x00110000, 0x00000002 },
239     	{ 0x000380e5, 0x00000002 },
240     	{ 0x000000c6, 0x0000001c },
241     	{ 0x000610ab, 0x00000018 },
242     	{ 0x844075bd, 0x00000002 },
243     	{ 0x000610aa, 0x00000018 },
244     	{ 0x840075bb, 0x00000002 },
245     	{ 0x000610ab, 0x00000018 },
246     	{ 0x844075bc, 0x00000002 },
247     	{ 0x000000c9, 0x00000004 },
248     	{ 0x804075bd, 0x00000002 },
249     	{ 0x800075bb, 0x00000002 },
250     	{ 0x804075bc, 0x00000002 },
251     	{ 0x00108000, 0x00000002 },
252     	{ 0x01400000, 0x00000002 },
253     	{ 0x006000cd, 0x0000000c },
254     	{ 0x20c07000, 0x00000020 },
255     	{ 0x000000cf, 0x00000012 },
256     	{ 0x00800000, 0x00000006 },
257     	{ 0x0080751d, 0x00000006 },
258     	{ 0000000000, 0000000000 },
259     	{ 0x0000775c, 0x00000002 },
260     	{ 0x00a05000, 0x00000002 },
261     	{ 0x00661000, 0x00000002 },
262     	{ 0x0460275d, 0x00000020 },
263     	{ 0x00004000, 0000000000 },
264     	{ 0x01e00830, 0x00000002 },
265     	{ 0x21007000, 0000000000 },
266     	{ 0x6464614d, 0000000000 },
267     	{ 0x69687420, 0000000000 },
268     	{ 0x00000073, 0000000000 },
269     	{ 0000000000, 0000000000 },
270     	{ 0x00005000, 0x00000002 },
271     	{ 0x000380d0, 0x00000002 },
272     	{ 0x040025e0, 0x00000002 },
273     	{ 0x000075e1, 0000000000 },
274     	{ 0x00000001, 0000000000 },
275     	{ 0x000380e0, 0x00000002 },
276     	{ 0x04002394, 0x00000002 },
277     	{ 0x00005000, 0000000000 },
278     	{ 0000000000, 0000000000 },
279     	{ 0000000000, 0000000000 },
280     	{ 0x00000008, 0000000000 },
281     	{ 0x00000004, 0000000000 },
282     	{ 0000000000, 0000000000 },
283     	{ 0000000000, 0000000000 },
284     	{ 0000000000, 0000000000 },
285     	{ 0000000000, 0000000000 },
286     	{ 0000000000, 0000000000 },
287     	{ 0000000000, 0000000000 },
288     	{ 0000000000, 0000000000 },
289     	{ 0000000000, 0000000000 },
290     	{ 0000000000, 0000000000 },
291     	{ 0000000000, 0000000000 },
292     	{ 0000000000, 0000000000 },
293     	{ 0000000000, 0000000000 },
294     	{ 0000000000, 0000000000 },
295     	{ 0000000000, 0000000000 },
296     	{ 0000000000, 0000000000 },
297     	{ 0000000000, 0000000000 },
298     	{ 0000000000, 0000000000 },
299     	{ 0000000000, 0000000000 },
300     	{ 0000000000, 0000000000 },
301     	{ 0000000000, 0000000000 },
302     	{ 0000000000, 0000000000 },
303     	{ 0000000000, 0000000000 },
304     	{ 0000000000, 0000000000 },
305     	{ 0000000000, 0000000000 },
306     };
307     
308     
309     int RADEON_READ_PLL(drm_device_t *dev, int addr)
310     {
311     	drm_radeon_private_t *dev_priv = dev->dev_private;
312     
313     	RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
314     	return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
315     }
316     
317     #if RADEON_FIFO_DEBUG
318     static void radeon_status( drm_radeon_private_t *dev_priv )
319     {
320     	printk( "%s:\n", __FUNCTION__ );
321     	printk( "RBBM_STATUS = 0x%08x\n",
322     		(unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) );
323     	printk( "CP_RB_RTPR = 0x%08x\n",
324     		(unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
325     	printk( "CP_RB_WTPR = 0x%08x\n",
326     		(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
327     	printk( "AIC_CNTL = 0x%08x\n",
328     		(unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
329     	printk( "AIC_STAT = 0x%08x\n",
330     		(unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
331     	printk( "AIC_PT_BASE = 0x%08x\n",
332     		(unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
333     	printk( "TLB_ADDR = 0x%08x\n",
334     		(unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
335     	printk( "TLB_DATA = 0x%08x\n",
336     		(unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
337     }
338     #endif
339     
340     
341     /* ================================================================
342      * Engine, FIFO control
343      */
344     
345     static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv )
346     {
347     	u32 tmp;
348     	int i;
349     
350     	tmp  = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
351     	tmp |= RADEON_RB2D_DC_FLUSH_ALL;
352     	RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
353     
354     	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
355     		if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT )
356     		       & RADEON_RB2D_DC_BUSY) ) {
357     			return 0;
358     		}
359     		udelay( 1 );
360     	}
361     
362     #if RADEON_FIFO_DEBUG
363     	DRM_ERROR( "failed!\n" );
364     	radeon_status( dev_priv );
365     #endif
366     	return -EBUSY;
367     }
368     
369     static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
370     				    int entries )
371     {
372     	int i;
373     
374     	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
375     		int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
376     			      & RADEON_RBBM_FIFOCNT_MASK );
377     		if ( slots >= entries ) return 0;
378     		udelay( 1 );
379     	}
380     
381     #if RADEON_FIFO_DEBUG
382     	DRM_ERROR( "failed!\n" );
383     	radeon_status( dev_priv );
384     #endif
385     	return -EBUSY;
386     }
387     
388     static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
389     {
390     	int i, ret;
391     
392     	ret = radeon_do_wait_for_fifo( dev_priv, 64 );
393     	if ( ret < 0 ) return ret;
394     
395     	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
396     		if ( !(RADEON_READ( RADEON_RBBM_STATUS )
397     		       & RADEON_RBBM_ACTIVE) ) {
398     			radeon_do_pixcache_flush( dev_priv );
399     			return 0;
400     		}
401     		udelay( 1 );
402     	}
403     
404     #if RADEON_FIFO_DEBUG
405     	DRM_ERROR( "failed!\n" );
406     	radeon_status( dev_priv );
407     #endif
408     	return -EBUSY;
409     }
410     
411     
412     /* ================================================================
413      * CP control, initialization
414      */
415     
416     /* Load the microcode for the CP */
417     static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
418     {
419     	int i;
420     	DRM_DEBUG( "%s\n", __FUNCTION__ );
421     
422     	radeon_do_wait_for_idle( dev_priv );
423     
424     	RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
425     	for ( i = 0 ; i < 256 ; i++ ) {
426     		RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
427     			      radeon_cp_microcode[i][1] );
428     		RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
429     			      radeon_cp_microcode[i][0] );
430     	}
431     }
432     
433     /* Flush any pending commands to the CP.  This should only be used just
434      * prior to a wait for idle, as it informs the engine that the command
435      * stream is ending.
436      */
437     static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
438     {
439     	DRM_DEBUG( "%s\n", __FUNCTION__ );
440     #if 0
441     	u32 tmp;
442     
443     	tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31);
444     	RADEON_WRITE( RADEON_CP_RB_WPTR, tmp );
445     #endif
446     }
447     
448     /* Wait for the CP to go idle.
449      */
450     int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
451     {
452     	RING_LOCALS;
453     	DRM_DEBUG( "%s\n", __FUNCTION__ );
454     
455     	BEGIN_RING( 6 );
456     
457     	RADEON_PURGE_CACHE();
458     	RADEON_PURGE_ZCACHE();
459     	RADEON_WAIT_UNTIL_IDLE();
460     
461     	ADVANCE_RING();
462     
463     	return radeon_do_wait_for_idle( dev_priv );
464     }
465     
466     /* Start the Command Processor.
467      */
468     static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
469     {
470     	RING_LOCALS;
471     	DRM_DEBUG( "%s\n", __FUNCTION__ );
472     
473     	radeon_do_wait_for_idle( dev_priv );
474     
475     	RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode );
476     
477     	dev_priv->cp_running = 1;
478     
479     	BEGIN_RING( 6 );
480     
481     	RADEON_PURGE_CACHE();
482     	RADEON_PURGE_ZCACHE();
483     	RADEON_WAIT_UNTIL_IDLE();
484     
485     	ADVANCE_RING();
486     }
487     
488     /* Reset the Command Processor.  This will not flush any pending
489      * commands, so you must wait for the CP command stream to complete
490      * before calling this routine.
491      */
492     static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
493     {
494     	u32 cur_read_ptr;
495     	DRM_DEBUG( "%s\n", __FUNCTION__ );
496     
497     	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
498     	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
499     	*dev_priv->ring.head = cur_read_ptr;
500     	dev_priv->ring.tail = cur_read_ptr;
501     }
502     
503     /* Stop the Command Processor.  This will not flush any pending
504      * commands, so you must flush the command stream and wait for the CP
505      * to go idle before calling this routine.
506      */
507     static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
508     {
509     	DRM_DEBUG( "%s\n", __FUNCTION__ );
510     
511     	RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
512     
513     	dev_priv->cp_running = 0;
514     }
515     
516     /* Reset the engine.  This will stop the CP if it is running.
517      */
518     static int radeon_do_engine_reset( drm_device_t *dev )
519     {
520     	drm_radeon_private_t *dev_priv = dev->dev_private;
521     	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
522     	DRM_DEBUG( "%s\n", __FUNCTION__ );
523     
524     	radeon_do_pixcache_flush( dev_priv );
525     
526     	clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
527     	mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
528     
529     	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
530     					      RADEON_FORCEON_MCLKA |
531     					      RADEON_FORCEON_MCLKB |
532      					      RADEON_FORCEON_YCLKA |
533     					      RADEON_FORCEON_YCLKB |
534     					      RADEON_FORCEON_MC |
535     					      RADEON_FORCEON_AIC ) );
536     
537     	rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
538     
539     	RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset |
540     						RADEON_SOFT_RESET_CP |
541     						RADEON_SOFT_RESET_HI |
542     						RADEON_SOFT_RESET_SE |
543     						RADEON_SOFT_RESET_RE |
544     						RADEON_SOFT_RESET_PP |
545     						RADEON_SOFT_RESET_E2 |
546     						RADEON_SOFT_RESET_RB ) );
547     	RADEON_READ( RADEON_RBBM_SOFT_RESET );
548     	RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset &
549     						~( RADEON_SOFT_RESET_CP |
550     						   RADEON_SOFT_RESET_HI |
551     						   RADEON_SOFT_RESET_SE |
552     						   RADEON_SOFT_RESET_RE |
553     						   RADEON_SOFT_RESET_PP |
554     						   RADEON_SOFT_RESET_E2 |
555     						   RADEON_SOFT_RESET_RB ) ) );
556     	RADEON_READ( RADEON_RBBM_SOFT_RESET );
557     
558     
559     	RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl );
560     	RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
561     	RADEON_WRITE( RADEON_RBBM_SOFT_RESET,  rbbm_soft_reset );
562     
563     	/* Reset the CP ring */
564     	radeon_do_cp_reset( dev_priv );
565     
566     	/* The CP is no longer running after an engine reset */
567     	dev_priv->cp_running = 0;
568     
569     	/* Reset any pending vertex, indirect buffers */
570     	radeon_freelist_reset( dev );
571     
572     	return 0;
573     }
574     
575     static void radeon_cp_init_ring_buffer( drm_device_t *dev,
576     				        drm_radeon_private_t *dev_priv )
577     {
578     	u32 ring_start, cur_read_ptr;
579     	u32 tmp;
580     
581     	/* Initialize the memory controller */
582     	RADEON_WRITE( RADEON_MC_FB_LOCATION,
583     		      (dev_priv->agp_vm_start - 1) & 0xffff0000 );
584     
585     	if ( !dev_priv->is_pci ) {
586     		RADEON_WRITE( RADEON_MC_AGP_LOCATION,
587     			      (((dev_priv->agp_vm_start - 1 +
588     				 dev_priv->agp_size) & 0xffff0000) |
589     			       (dev_priv->agp_vm_start >> 16)) );
590     	}
591     
592     #if __REALLY_HAVE_AGP
593     	if ( !dev_priv->is_pci )
594     		ring_start = (dev_priv->cp_ring->offset
595     			      - dev->agp->base
596     			      + dev_priv->agp_vm_start);
597            else
598     #endif
599     		ring_start = (dev_priv->cp_ring->offset
600     			      - dev->sg->handle
601     			      + dev_priv->agp_vm_start);
602     
603     	RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
604     
605     	/* Set the write pointer delay */
606     	RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 );
607     
608     	/* Initialize the ring buffer's read and write pointers */
609     	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
610     	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
611     	*dev_priv->ring.head = cur_read_ptr;
612     	dev_priv->ring.tail = cur_read_ptr;
613     
614     	if ( !dev_priv->is_pci ) {
615     		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
616     			      dev_priv->ring_rptr->offset );
617     	} else {
618     		drm_sg_mem_t *entry = dev->sg;
619     		unsigned long tmp_ofs, page_ofs;
620     
621     		tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
622     		page_ofs = tmp_ofs >> PAGE_SHIFT;
623     
624     		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
625     			     entry->busaddr[page_ofs]);
626     		DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
627     			   entry->busaddr[page_ofs],
628     			   entry->handle + tmp_ofs );
629     	}
630     
631     	/* Set ring buffer size */
632     	RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
633     
634     	radeon_do_wait_for_idle( dev_priv );
635     
636     	/* Turn on bus mastering */
637     	tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
638     	RADEON_WRITE( RADEON_BUS_CNTL, tmp );
639     
640     	/* Sync everything up */
641     	RADEON_WRITE( RADEON_ISYNC_CNTL,
642     		      (RADEON_ISYNC_ANY2D_IDLE3D |
643     		       RADEON_ISYNC_ANY3D_IDLE2D |
644     		       RADEON_ISYNC_WAIT_IDLEGUI |
645     		       RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
646     }
647     
648     static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
649     {
650     	drm_radeon_private_t *dev_priv;
651     	struct list_head *list;
652     	u32 tmp;
653     	DRM_DEBUG( "%s\n", __FUNCTION__ );
654     
655     	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
656     	if ( dev_priv == NULL )
657     		return -ENOMEM;
658     
659     	memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
660     
661     	dev_priv->is_pci = init->is_pci;
662     
663     #if !defined(PCIGART_ENABLED)
664     	/* PCI support is not 100% working, so we disable it here.
665     	 */
666     	if ( dev_priv->is_pci ) {
667     		DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
668     		dev->dev_private = (void *)dev_priv;
669     		radeon_do_cleanup_cp(dev);
670     		return -EINVAL;
671     	}
672     #endif
673     
674     	if ( dev_priv->is_pci && !dev->sg ) {
675     		DRM_ERROR( "PCI GART memory not allocated!\n" );
676     		dev->dev_private = (void *)dev_priv;
677     		radeon_do_cleanup_cp(dev);
678     		return -EINVAL;
679     	}
680     
681     	dev_priv->usec_timeout = init->usec_timeout;
682     	if ( dev_priv->usec_timeout < 1 ||
683     	     dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
684     		DRM_DEBUG( "TIMEOUT problem!\n" );
685     		dev->dev_private = (void *)dev_priv;
686     		radeon_do_cleanup_cp(dev);
687     		return -EINVAL;
688     	}
689     
690     	dev_priv->cp_mode = init->cp_mode;
691     
692     	/* Simple idle check.
693     	 */
694     	atomic_set( &dev_priv->idle_count, 0 );
695     
696     	/* We don't support anything other than bus-mastering ring mode,
697     	 * but the ring can be in either AGP or PCI space for the ring
698     	 * read pointer.
699     	 */
700     	if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
701     	     ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
702     		DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
703     		dev->dev_private = (void *)dev_priv;
704     		radeon_do_cleanup_cp(dev);
705     		return -EINVAL;
706     	}
707     
708     	switch ( init->fb_bpp ) {
709     	case 16:
710     		dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
711     		break;
712     	case 32:
713     	default:
714     		dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
715     		break;
716     	}
717     	dev_priv->front_offset	= init->front_offset;
718     	dev_priv->front_pitch	= init->front_pitch;
719     	dev_priv->back_offset	= init->back_offset;
720     	dev_priv->back_pitch	= init->back_pitch;
721     
722     	switch ( init->depth_bpp ) {
723     	case 16:
724     		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
725     		break;
726     	case 32:
727     	default:
728     		dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
729     		break;
730     	}
731     	dev_priv->depth_offset	= init->depth_offset;
732     	dev_priv->depth_pitch	= init->depth_pitch;
733     
734     	dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
735     					(dev_priv->front_offset >> 10));
736     	dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
737     				       (dev_priv->back_offset >> 10));
738     	dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
739     					(dev_priv->depth_offset >> 10));
740     
741     	/* Hardware state for depth clears.  Remove this if/when we no
742     	 * longer clear the depth buffer with a 3D rectangle.  Hard-code
743     	 * all values to prevent unwanted 3D state from slipping through
744     	 * and screwing with the clear operation.
745     	 */
746     	dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
747     					   RADEON_Z_ENABLE |
748     					   (dev_priv->color_fmt << 10) |
749     					   RADEON_ZBLOCK16);
750     
751     	dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt |
752     						   RADEON_Z_TEST_ALWAYS |
753     						   RADEON_STENCIL_TEST_ALWAYS |
754     						   RADEON_STENCIL_S_FAIL_KEEP |
755     						   RADEON_STENCIL_ZPASS_KEEP |
756     						   RADEON_STENCIL_ZFAIL_KEEP |
757     						   RADEON_Z_WRITE_ENABLE);
758     
759     	dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
760     					 RADEON_BFACE_SOLID |
761     					 RADEON_FFACE_SOLID |
762     					 RADEON_FLAT_SHADE_VTX_LAST |
763     					 RADEON_DIFFUSE_SHADE_FLAT |
764     					 RADEON_ALPHA_SHADE_FLAT |
765     					 RADEON_SPECULAR_SHADE_FLAT |
766     					 RADEON_FOG_SHADE_FLAT |
767     					 RADEON_VTX_PIX_CENTER_OGL |
768     					 RADEON_ROUND_MODE_TRUNC |
769     					 RADEON_ROUND_PREC_8TH_PIX);
770     
771     	list_for_each(list, &dev->maplist->head) {
772     		drm_map_list_t *r_list = (drm_map_list_t *)list;
773     		if( r_list->map &&
774     		    r_list->map->type == _DRM_SHM &&
775     		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
776     			dev_priv->sarea = r_list->map;
777      			break;
778      		}
779      	}
780     	if(!dev_priv->sarea) {
781     		DRM_ERROR("could not find sarea!\n");
782     		dev->dev_private = (void *)dev_priv;
783     		radeon_do_cleanup_cp(dev);
784     		return -EINVAL;
785     	}
786     
787     	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
788     	if(!dev_priv->fb) {
789     		DRM_ERROR("could not find framebuffer!\n");
790     		dev->dev_private = (void *)dev_priv;
791     		radeon_do_cleanup_cp(dev);
792     		return -EINVAL;
793     	}
794     	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
795     	if(!dev_priv->mmio) {
796     		DRM_ERROR("could not find mmio region!\n");
797     		dev->dev_private = (void *)dev_priv;
798     		radeon_do_cleanup_cp(dev);
799     		return -EINVAL;
800     	}
801     	DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
802     	if(!dev_priv->cp_ring) {
803     		DRM_ERROR("could not find cp ring region!\n");
804     		dev->dev_private = (void *)dev_priv;
805     		radeon_do_cleanup_cp(dev);
806     		return -EINVAL;
807     	}
808     	DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
809     	if(!dev_priv->ring_rptr) {
810     		DRM_ERROR("could not find ring read pointer!\n");
811     		dev->dev_private = (void *)dev_priv;
812     		radeon_do_cleanup_cp(dev);
813     		return -EINVAL;
814     	}
815     	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
816     	if(!dev_priv->buffers) {
817     		DRM_ERROR("could not find dma buffer region!\n");
818     		dev->dev_private = (void *)dev_priv;
819     		radeon_do_cleanup_cp(dev);
820     		return -EINVAL;
821     	}
822     
823     	if ( !dev_priv->is_pci ) {
824     		DRM_FIND_MAP( dev_priv->agp_textures,
825     			      init->agp_textures_offset );
826     		if(!dev_priv->agp_textures) {
827     			DRM_ERROR("could not find agp texture region!\n");
828     			dev->dev_private = (void *)dev_priv;
829     			radeon_do_cleanup_cp(dev);
830     			return -EINVAL;
831     		}
832     	}
833     
834     	dev_priv->sarea_priv =
835     		(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
836     				       init->sarea_priv_offset);
837     
838     	if ( !dev_priv->is_pci ) {
839     		DRM_IOREMAP( dev_priv->cp_ring );
840     		DRM_IOREMAP( dev_priv->ring_rptr );
841     		DRM_IOREMAP( dev_priv->buffers );
842     		if(!dev_priv->cp_ring->handle ||
843     		   !dev_priv->ring_rptr->handle ||
844     		   !dev_priv->buffers->handle) {
845     			DRM_ERROR("could not find ioremap agp regions!\n");
846     			dev->dev_private = (void *)dev_priv;
847     			radeon_do_cleanup_cp(dev);
848     			return -EINVAL;
849     		}
850     	} else {
851     		dev_priv->cp_ring->handle =
852     			(void *)dev_priv->cp_ring->offset;
853     		dev_priv->ring_rptr->handle =
854     			(void *)dev_priv->ring_rptr->offset;
855     		dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
856     
857     		DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
858     			   dev_priv->cp_ring->handle );
859     		DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
860     			   dev_priv->ring_rptr->handle );
861     		DRM_DEBUG( "dev_priv->buffers->handle %p\n",
862     			   dev_priv->buffers->handle );
863     	}
864     
865     
866     	dev_priv->agp_size = init->agp_size;
867     	dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
868     #if __REALLY_HAVE_AGP
869     	if ( !dev_priv->is_pci )
870     		dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
871     						- dev->agp->base
872     						+ dev_priv->agp_vm_start);
873     	else
874     #endif
875     		dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
876     						- dev->sg->handle
877     						+ dev_priv->agp_vm_start);
878     
879     	DRM_DEBUG( "dev_priv->agp_size %d\n",
880     		   dev_priv->agp_size );
881     	DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n",
882     		   dev_priv->agp_vm_start );
883     	DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n",
884     		   dev_priv->agp_buffers_offset );
885     
886     	dev_priv->ring.head = ((__volatile__ u32 *)
887     			       dev_priv->ring_rptr->handle);
888     
889     	dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle;
890     	dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
891     			      + init->ring_size / sizeof(u32));
892     	dev_priv->ring.size = init->ring_size;
893     	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
894     
895     	dev_priv->ring.tail_mask =
896     		(dev_priv->ring.size / sizeof(u32)) - 1;
897     
898     	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
899     
900     #if 0
901     	/* Initialize the scratch register pointer.  This will cause
902     	 * the scratch register values to be written out to memory
903     	 * whenever they are updated.
904     	 * FIXME: This doesn't quite work yet, so we're disabling it
905     	 * for the release.
906     	 */
907     	RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset +
908     					    RADEON_SCRATCH_REG_OFFSET) );
909     	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
910     #endif
911     
912     	dev_priv->scratch = ((__volatile__ u32 *)
913     			     dev_priv->ring_rptr->handle +
914     			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
915     
916     	dev_priv->sarea_priv->last_frame = 0;
917     	RADEON_WRITE( RADEON_LAST_FRAME_REG,
918     		      dev_priv->sarea_priv->last_frame );
919     
920     	dev_priv->sarea_priv->last_dispatch = 0;
921     	RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
922     		      dev_priv->sarea_priv->last_dispatch );
923     
924     	dev_priv->sarea_priv->last_clear = 0;
925     	RADEON_WRITE( RADEON_LAST_CLEAR_REG,
926     		      dev_priv->sarea_priv->last_clear );
927     
928     	if ( dev_priv->is_pci ) {
929     		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
930     					    &dev_priv->bus_pci_gart)) {
931     			DRM_ERROR( "failed to init PCI GART!\n" );
932     			dev->dev_private = (void *)dev_priv;
933     			radeon_do_cleanup_cp(dev);
934     			return -ENOMEM;
935     		}
936     		/* Turn on PCI GART
937     		 */
938     		tmp = RADEON_READ( RADEON_AIC_CNTL )
939     		      | RADEON_PCIGART_TRANSLATE_EN;
940     		RADEON_WRITE( RADEON_AIC_CNTL, tmp );
941     
942     		/* set PCI GART page-table base address
943     		 */
944     		RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
945     
946     		/* set address range for PCI address translate
947     		 */
948     		RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
949     		RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
950     						  + dev_priv->agp_size - 1);
951     
952     		/* Turn off AGP aperture -- is this required for PCIGART?
953     		 */
954     		RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
955     		RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
956     	} else {
957     		/* Turn off PCI GART
958     		 */
959     		tmp = RADEON_READ( RADEON_AIC_CNTL )
960     		      & ~RADEON_PCIGART_TRANSLATE_EN;
961     		RADEON_WRITE( RADEON_AIC_CNTL, tmp );
962     	}
963     
964     	radeon_cp_load_microcode( dev_priv );
965     	radeon_cp_init_ring_buffer( dev, dev_priv );
966     
967     #if ROTATE_BUFS
968     	dev_priv->last_buf = 0;
969     #endif
970     
971     	dev->dev_private = (void *)dev_priv;
972     
973     	radeon_do_engine_reset( dev );
974     
975     	return 0;
976     }
977     
978     int radeon_do_cleanup_cp( drm_device_t *dev )
979     {
980     	DRM_DEBUG( "%s\n", __FUNCTION__ );
981     
982     	if ( dev->dev_private ) {
983     		drm_radeon_private_t *dev_priv = dev->dev_private;
984     
985     		if ( !dev_priv->is_pci ) {
986     			DRM_IOREMAPFREE( dev_priv->cp_ring );
987     			DRM_IOREMAPFREE( dev_priv->ring_rptr );
988     			DRM_IOREMAPFREE( dev_priv->buffers );
989     		} else {
990     			if (!DRM(ati_pcigart_cleanup)( dev,
991     						dev_priv->phys_pci_gart,
992     						dev_priv->bus_pci_gart ))
993     				DRM_ERROR( "failed to cleanup PCI GART!\n" );
994     		}
995     
996     		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
997     			   DRM_MEM_DRIVER );
998     		dev->dev_private = NULL;
999     	}
1000     
1001     	return 0;
1002     }
1003     
1004     int radeon_cp_init( struct inode *inode, struct file *filp,
1005     		    unsigned int cmd, unsigned long arg )
1006     {
1007             drm_file_t *priv = filp->private_data;
1008             drm_device_t *dev = priv->dev;
1009     	drm_radeon_init_t init;
1010     
1011     	if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) )
1012     		return -EFAULT;
1013     
1014     	switch ( init.func ) {
1015     	case RADEON_INIT_CP:
1016     		return radeon_do_init_cp( dev, &init );
1017     	case RADEON_CLEANUP_CP:
1018     		return radeon_do_cleanup_cp( dev );
1019     	}
1020     
1021     	return -EINVAL;
1022     }
1023     
1024     int radeon_cp_start( struct inode *inode, struct file *filp,
1025     		     unsigned int cmd, unsigned long arg )
1026     {
1027             drm_file_t *priv = filp->private_data;
1028             drm_device_t *dev = priv->dev;
1029     	drm_radeon_private_t *dev_priv = dev->dev_private;
1030     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1031     
1032     	LOCK_TEST_WITH_RETURN( dev );
1033     
1034     	if ( dev_priv->cp_running ) {
1035     		DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
1036     		return 0;
1037     	}
1038     	if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) {
1039     		DRM_DEBUG( "%s called with bogus CP mode (%d)\n",
1040     			   __FUNCTION__, dev_priv->cp_mode );
1041     		return 0;
1042     	}
1043     
1044     	radeon_do_cp_start( dev_priv );
1045     
1046     	return 0;
1047     }
1048     
1049     /* Stop the CP.  The engine must have been idled before calling this
1050      * routine.
1051      */
1052     int radeon_cp_stop( struct inode *inode, struct file *filp,
1053     		    unsigned int cmd, unsigned long arg )
1054     {
1055             drm_file_t *priv = filp->private_data;
1056             drm_device_t *dev = priv->dev;
1057     	drm_radeon_private_t *dev_priv = dev->dev_private;
1058     	drm_radeon_cp_stop_t stop;
1059     	int ret;
1060     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1061     
1062     	LOCK_TEST_WITH_RETURN( dev );
1063     
1064     	if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
1065     		return -EFAULT;
1066     
1067     	/* Flush any pending CP commands.  This ensures any outstanding
1068     	 * commands are exectuted by the engine before we turn it off.
1069     	 */
1070     	if ( stop.flush ) {
1071     		radeon_do_cp_flush( dev_priv );
1072     	}
1073     
1074     	/* If we fail to make the engine go idle, we return an error
1075     	 * code so that the DRM ioctl wrapper can try again.
1076     	 */
1077     	if ( stop.idle ) {
1078     		ret = radeon_do_cp_idle( dev_priv );
1079     		if ( ret < 0 ) return ret;
1080     	}
1081     
1082     	/* Finally, we can turn off the CP.  If the engine isn't idle,
1083     	 * we will get some dropped triangles as they won't be fully
1084     	 * rendered before the CP is shut down.
1085     	 */
1086     	radeon_do_cp_stop( dev_priv );
1087     
1088     	/* Reset the engine */
1089     	radeon_do_engine_reset( dev );
1090     
1091     	return 0;
1092     }
1093     
1094     /* Just reset the CP ring.  Called as part of an X Server engine reset.
1095      */
1096     int radeon_cp_reset( struct inode *inode, struct file *filp,
1097     		     unsigned int cmd, unsigned long arg )
1098     {
1099             drm_file_t *priv = filp->private_data;
1100             drm_device_t *dev = priv->dev;
1101     	drm_radeon_private_t *dev_priv = dev->dev_private;
1102     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1103     
1104     	LOCK_TEST_WITH_RETURN( dev );
1105     
1106     	if ( !dev_priv ) {
1107     		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
1108     		return -EINVAL;
1109     	}
1110     
1111     	radeon_do_cp_reset( dev_priv );
1112     
1113     	/* The CP is no longer running after an engine reset */
1114     	dev_priv->cp_running = 0;
1115     
1116     	return 0;
1117     }
1118     
1119     int radeon_cp_idle( struct inode *inode, struct file *filp,
1120     		    unsigned int cmd, unsigned long arg )
1121     {
1122             drm_file_t *priv = filp->private_data;
1123             drm_device_t *dev = priv->dev;
1124     	drm_radeon_private_t *dev_priv = dev->dev_private;
1125     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1126     
1127     	LOCK_TEST_WITH_RETURN( dev );
1128     
1129     	return radeon_do_cp_idle( dev_priv );
1130     }
1131     
1132     int radeon_engine_reset( struct inode *inode, struct file *filp,
1133     			 unsigned int cmd, unsigned long arg )
1134     {
1135             drm_file_t *priv = filp->private_data;
1136             drm_device_t *dev = priv->dev;
1137     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1138     
1139     	LOCK_TEST_WITH_RETURN( dev );
1140     
1141     	return radeon_do_engine_reset( dev );
1142     }
1143     
1144     
1145     /* ================================================================
1146      * Fullscreen mode
1147      */
1148     
1149     static int radeon_do_init_pageflip( drm_device_t *dev )
1150     {
1151     	drm_radeon_private_t *dev_priv = dev->dev_private;
1152     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1153     
1154     	dev_priv->crtc_offset =      RADEON_READ( RADEON_CRTC_OFFSET );
1155     	dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
1156     
1157     	RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
1158     	RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
1159     		      dev_priv->crtc_offset_cntl |
1160     		      RADEON_CRTC_OFFSET_FLIP_CNTL );
1161     
1162     	dev_priv->page_flipping = 1;
1163     	dev_priv->current_page = 0;
1164     
1165     	return 0;
1166     }
1167     
1168     int radeon_do_cleanup_pageflip( drm_device_t *dev )
1169     {
1170     	drm_radeon_private_t *dev_priv = dev->dev_private;
1171     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1172     
1173     	RADEON_WRITE( RADEON_CRTC_OFFSET,      dev_priv->crtc_offset );
1174     	RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
1175     
1176     	dev_priv->page_flipping = 0;
1177     	dev_priv->current_page = 0;
1178     
1179     	return 0;
1180     }
1181     
1182     int radeon_fullscreen( struct inode *inode, struct file *filp,
1183     		       unsigned int cmd, unsigned long arg )
1184     {
1185             drm_file_t *priv = filp->private_data;
1186             drm_device_t *dev = priv->dev;
1187     	drm_radeon_fullscreen_t fs;
1188     
1189     	LOCK_TEST_WITH_RETURN( dev );
1190     
1191     	if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
1192     			     sizeof(fs) ) )
1193     		return -EFAULT;
1194     
1195     	switch ( fs.func ) {
1196     	case RADEON_INIT_FULLSCREEN:
1197     		return radeon_do_init_pageflip( dev );
1198     	case RADEON_CLEANUP_FULLSCREEN:
1199     		return radeon_do_cleanup_pageflip( dev );
1200     	}
1201     
1202     	return -EINVAL;
1203     }
1204     
1205     
1206     /* ================================================================
1207      * Freelist management
1208      */
1209     #define RADEON_BUFFER_USED	0xffffffff
1210     #define RADEON_BUFFER_FREE	0
1211     
1212     #if 0
1213     static int radeon_freelist_init( drm_device_t *dev )
1214     {
1215     	drm_device_dma_t *dma = dev->dma;
1216     	drm_radeon_private_t *dev_priv = dev->dev_private;
1217     	drm_buf_t *buf;
1218     	drm_radeon_buf_priv_t *buf_priv;
1219     	drm_radeon_freelist_t *entry;
1220     	int i;
1221     
1222     	dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t),
1223     				     DRM_MEM_DRIVER );
1224     	if ( dev_priv->head == NULL )
1225     		return -ENOMEM;
1226     
1227     	memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) );
1228     	dev_priv->head->age = RADEON_BUFFER_USED;
1229     
1230     	for ( i = 0 ; i < dma->buf_count ; i++ ) {
1231     		buf = dma->buflist[i];
1232     		buf_priv = buf->dev_private;
1233     
1234     		entry = DRM(alloc)( sizeof(drm_radeon_freelist_t),
1235     				    DRM_MEM_DRIVER );
1236     		if ( !entry ) return -ENOMEM;
1237     
1238     		entry->age = RADEON_BUFFER_FREE;
1239     		entry->buf = buf;
1240     		entry->prev = dev_priv->head;
1241     		entry->next = dev_priv->head->next;
1242     		if ( !entry->next )
1243     			dev_priv->tail = entry;
1244     
1245     		buf_priv->discard = 0;
1246     		buf_priv->dispatched = 0;
1247     		buf_priv->list_entry = entry;
1248     
1249     		dev_priv->head->next = entry;
1250     
1251     		if ( dev_priv->head->next )
1252     			dev_priv->head->next->prev = entry;
1253     	}
1254     
1255     	return 0;
1256     
1257     }
1258     #endif
1259     
1260     drm_buf_t *radeon_freelist_get( drm_device_t *dev )
1261     {
1262     	drm_device_dma_t *dma = dev->dma;
1263     	drm_radeon_private_t *dev_priv = dev->dev_private;
1264     	drm_radeon_buf_priv_t *buf_priv;
1265     	drm_buf_t *buf;
1266     	int i, t;
1267     #if ROTATE_BUFS
1268     	int start;
1269     #endif
1270     
1271     	/* FIXME: Optimize -- use freelist code */
1272     
1273     	for ( i = 0 ; i < dma->buf_count ; i++ ) {
1274     		buf = dma->buflist[i];
1275     		buf_priv = buf->dev_private;
1276     		if ( buf->pid == 0 ) {
1277     			DRM_DEBUG( "  ret buf=%d last=%d pid=0\n",
1278     				   buf->idx, dev_priv->last_buf );
1279     			return buf;
1280     		}
1281     		DRM_DEBUG( "    skipping buf=%d pid=%d\n",
1282     			   buf->idx, buf->pid );
1283     	}
1284     
1285     #if ROTATE_BUFS
1286     	if ( ++dev_priv->last_buf >= dma->buf_count )
1287     		dev_priv->last_buf = 0;
1288     	start = dev_priv->last_buf;
1289     #endif
1290     	for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
1291     #if 0
1292     		/* FIXME: Disable this for now */
1293     		u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH];
1294     #else
1295     		u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG );
1296     #endif
1297     #if ROTATE_BUFS
1298     		for ( i = start ; i < dma->buf_count ; i++ ) {
1299     #else
1300     		for ( i = 0 ; i < dma->buf_count ; i++ ) {
1301     #endif
1302     			buf = dma->buflist[i];
1303     			buf_priv = buf->dev_private;
1304     			if ( buf->pending && buf_priv->age <= done_age ) {
1305     				/* The buffer has been processed, so it
1306     				 * can now be used.
1307     				 */
1308     				buf->pending = 0;
1309     				DRM_DEBUG( "  ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age );
1310     				return buf;
1311     			}
1312     			DRM_DEBUG( "    skipping buf=%d age=%d done=%d\n",
1313     				   buf->idx, buf_priv->age,
1314     				   done_age );
1315     #if ROTATE_BUFS
1316     			start = 0;
1317     #endif
1318     		}
1319     		udelay( 1 );
1320     	}
1321     
1322     	DRM_ERROR( "returning NULL!\n" );
1323     	return NULL;
1324     }
1325     
1326     void radeon_freelist_reset( drm_device_t *dev )
1327     {
1328     	drm_device_dma_t *dma = dev->dma;
1329     #if ROTATE_BUFS
1330     	drm_radeon_private_t *dev_priv = dev->dev_private;
1331     #endif
1332     	int i;
1333     
1334     #if ROTATE_BUFS
1335     	dev_priv->last_buf = 0;
1336     #endif
1337     	for ( i = 0 ; i < dma->buf_count ; i++ ) {
1338     		drm_buf_t *buf = dma->buflist[i];
1339     		drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1340     		buf_priv->age = 0;
1341     	}
1342     }
1343     
1344     
1345     /* ================================================================
1346      * CP command submission
1347      */
1348     
1349     int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
1350     {
1351     	drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
1352     	int i;
1353     
1354     	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
1355     		radeon_update_ring_snapshot( ring );
1356     		if ( ring->space > n )
1357     			return 0;
1358     		udelay( 1 );
1359     	}
1360     
1361     	/* FIXME: This return value is ignored in the BEGIN_RING macro! */
1362     #if RADEON_FIFO_DEBUG
1363     	radeon_status( dev_priv );
1364     	DRM_ERROR( "failed!\n" );
1365     #endif
1366     	return -EBUSY;
1367     }
1368     
1369     static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
1370     {
1371     	int i;
1372     	drm_buf_t *buf;
1373     
1374     	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
1375     		buf = radeon_freelist_get( dev );
1376     		if ( !buf ) return -EAGAIN;
1377     
1378     		buf->pid = current->pid;
1379     
1380     		if ( copy_to_user( &d->request_indices[i], &buf->idx,
1381     				   sizeof(buf->idx) ) )
1382     			return -EFAULT;
1383     		if ( copy_to_user( &d->request_sizes[i], &buf->total,
1384     				   sizeof(buf->total) ) )
1385     			return -EFAULT;
1386     
1387     		d->granted_count++;
1388     	}
1389     	return 0;
1390     }
1391     
1392     int radeon_cp_buffers( struct inode *inode, struct file *filp,
1393     		       unsigned int cmd, unsigned long arg )
1394     {
1395     	drm_file_t *priv = filp->private_data;
1396     	drm_device_t *dev = priv->dev;
1397     	drm_device_dma_t *dma = dev->dma;
1398     	int ret = 0;
1399     	drm_dma_t d;
1400     
1401     	LOCK_TEST_WITH_RETURN( dev );
1402     
1403     	if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
1404     		return -EFAULT;
1405     
1406     	/* Please don't send us buffers.
1407     	 */
1408     	if ( d.send_count != 0 ) {
1409     		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
1410     			   current->pid, d.send_count );
1411     		return -EINVAL;
1412     	}
1413     
1414     	/* We'll send you buffers.
1415     	 */
1416     	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
1417     		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
1418     			   current->pid, d.request_count, dma->buf_count );
1419     		return -EINVAL;
1420     	}
1421     
1422     	d.granted_count = 0;
1423     
1424     	if ( d.request_count ) {
1425     		ret = radeon_cp_get_buffers( dev, &d );
1426     	}
1427     
1428     	if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
1429     		return -EFAULT;
1430     
1431     	return ret;
1432     }
1433