1 /* 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 
R128_READ_PLL(drm_device_t * dev,int addr)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 
r128_do_pixcache_flush(drm_r128_private_t * dev_priv)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 
r128_do_wait_for_fifo(drm_r128_private_t * dev_priv,int entries)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 
r128_do_wait_for_idle(drm_r128_private_t * dev_priv)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 */
r128_cce_load_microcode(drm_r128_private_t * dev_priv)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  */
r128_do_cce_flush(drm_r128_private_t * dev_priv)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  */
r128_do_cce_idle(drm_r128_private_t * dev_priv)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  */
r128_do_cce_start(drm_r128_private_t * dev_priv)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  */
r128_do_cce_reset(drm_r128_private_t * dev_priv)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  */
r128_do_cce_stop(drm_r128_private_t * dev_priv)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  */
r128_do_engine_reset(drm_device_t * dev)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 
r128_cce_init_ring_buffer(drm_device_t * dev)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 
r128_do_init_cce(drm_device_t * dev,drm_r128_init_t * init)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 
r128_do_cleanup_cce(drm_device_t * dev)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 
r128_cce_init(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 
r128_cce_start(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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  */
r128_cce_stop(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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  */
r128_cce_reset(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 
r128_cce_idle(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 
r128_engine_reset(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 
r128_freelist_get(drm_device_t * dev)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 
r128_freelist_reset(drm_device_t * dev)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 
r128_wait_ring(drm_r128_private_t * dev_priv,int n)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 
r128_update_ring_snapshot(drm_r128_private_t * dev_priv)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  */
r128_do_submit_packet(drm_r128_private_t * dev_priv,u32 * buffer,int count)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  */
r128_cce_packet(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 
r128_cce_get_buffers(drm_device_t * dev,drm_dma_t * d)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 
r128_cce_buffers(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)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 }
1254