xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon/CP_setup.c (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 /*
2 	Copyright (c) 2002, Thomas Kurschel
3 
4 
5 	Part of Radeon accelerant
6 
7 	CP initialization/sync/cleanup.
8 
9 	It also handles command buffer synchronization.
10 
11 	non-local memory is used as following:
12 	- 2048 dwords for ring buffer
13 	- 253 indirect buffers a 4k (1024 dwords)
14 	- 8 dwords for returned data (i.e. current read ptr)
15 	  & 6 dwords for "scratch registers"
16 
17 	usage of scratch registers:
18 	- reg 0 = reached engine.count
19 
20 	with a granularity of 4 KByte, we need 2+253+1=256 blocks, which is exactly 1 MB
21 */
22 
23 #include "radeon_driver.h"
24 #include "CPMicroCode.h"
25 #include "mmio.h"
26 #include "cp_regs.h"
27 #include "pll_regs.h"
28 #include "rbbm_regs.h"
29 #include "buscntrl_regs.h"
30 #include "utils.h"
31 #include "pll_access.h"
32 
33 #include "log_coll.h"
34 #include "log_enum.h"
35 
36 #include <string.h>
37 
38 #if 0
39 
40 // macros for user-space
41 
42 #define ALLOC_MEM( asize, mem_type, aglobal, handle, offset ) \
43 	{ \
44 		radeon_alloc_mem am; \
45 \
46 		am.magic = RADEON_PRIVATE_DATA_MAGIC; \
47 		am.size = (asize) * 4; \
48 		am.memory_type = (mt_nonlocal); \
49 		am.global = (aglobal); \
50 \
51 		res = ioctl( ai->fd, RADEON_ALLOC_MEM, &am ); \
52 		if( res == B_OK ) \
53 			*(handle) = am.handle; \
54 			*(offset) = am.offset; \
55 	}
56 
57 #define MEM2CPU( mem ) \
58 	((uint32 *)(ai->mapped_memory[(mem).memory_type].data + (mem).offset))
59 
60 #define MEM2GC( mem ) ((mem).offset + si->memory[(mem).memory_type].virtual_addr_start)
61 
62 #define FREE_MEM( mem_type, handle ) \
63 	{ \
64 		radeon_free_mem fm; \
65 \
66 		fm.magic = RADEON_PRIVATE_DATA_MAGIC; \
67 		fm.memory_type = mem_type; \
68 		fm.handle = offset; \
69 \
70 		ioctl( ai->fd, RADEON_FREE_MEM, &fm ); \
71 	}
72 
73 #else
74 
75 // macros for kernel-space
76 
77 // allocate memory
78 // if memory_type is non-local, it is replaced with default non-local type
79 #define ALLOC_MEM( asize, mem_type, aglobal, handle, offset ) \
80 	if( mem_type == mt_nonlocal ) \
81 		mem_type = di->si->nonlocal_type; \
82 	res = mem_alloc( di->memmgr[mem_type], asize, NULL, handle, offset );
83 
84 // get address as seen by program to access allocated memory
85 // (memory_type must _not_ be non-local, see ALLOC_MEM)
86 #define MEM2CPU( memory_type, offset ) \
87 	((uint8 *)(memory_type == mt_local ? di->si->local_mem : \
88 	(memory_type == mt_PCI ? di->pci_gart.buffer.ptr : di->agp_gart.buffer.ptr)) \
89 	+ (offset))
90 
91 // get graphics card's virtual address of allocated memory
92 // (memory_type must _not_ be non-local, see ALLOC_MEM)
93 #define MEM2GC( memory_type, offset ) \
94 	(di->si->memory[(memory_type)].virtual_addr_start + (offset))
95 
96 // free memory
97 // if memory_type is non-local, it is replaced with default non-local type
98 #define FREE_MEM( mem_type, handle ) \
99 	mem_free( \
100 		di->memmgr[ mem_type == mt_nonlocal ? di->si->nonlocal_type : mem_type], \
101 		handle, NULL );
102 
103 #endif
104 
105 
106 void Radeon_DiscardAllIndirectBuffers( device_info *di );
107 
108 #define RADEON_SCRATCH_REG_OFFSET	32
109 
110 
111 void Radeon_FlushPixelCache( device_info *di );
112 
113 // wait until engine is idle;
114 // acquire_lock - 	true, if lock must be hold
115 //					false, if lock is already acquired
116 // keep_lock -		true, keep lock on exit (only valid if acquire_lock is true)
117 void Radeon_WaitForIdle( device_info *di, bool acquire_lock, bool keep_lock )
118 {
119 	if( acquire_lock )
120 		ACQUIRE_BEN( di->si->cp.lock );
121 
122 	Radeon_WaitForFifo( di, 64 );
123 
124 	while( 1 ) {
125 		bigtime_t start_time = system_time();
126 
127 		do {
128 			if( (INREG( di->regs, RADEON_RBBM_STATUS ) & RADEON_RBBM_ACTIVE) == 0 ) {
129 				Radeon_FlushPixelCache( di );
130 
131 				if( acquire_lock && !keep_lock)
132 					RELEASE_BEN( di->si->cp.lock );
133 
134 				return;
135 			}
136 
137 			snooze( 1 );
138 		} while( system_time() - start_time < 1000000 );
139 
140 		SHOW_ERROR( 3, "Engine didn't become idle (rbbm_status=%lx, cp_stat=%lx, tlb_address=%lx, tlb_data=%lx)",
141 			INREG( di->regs, RADEON_RBBM_STATUS ),
142 			INREG( di->regs, RADEON_CP_STAT ),
143 			INREG( di->regs, RADEON_AIC_TLB_ADDR ),
144 			INREG( di->regs, RADEON_AIC_TLB_DATA ));
145 
146 		LOG( di->si->log, _Radeon_WaitForIdle );
147 
148 		Radeon_ResetEngine( di );
149 	}
150 }
151 
152 
153 // wait until "entries" FIFO entries are empty
154 // lock must be hold
155 void Radeon_WaitForFifo( device_info *di, int entries )
156 {
157 	while( 1 ) {
158 		bigtime_t start_time = system_time();
159 
160 		do {
161 			int slots = INREG( di->regs, RADEON_RBBM_STATUS ) & RADEON_RBBM_FIFOCNT_MASK;
162 
163 			if ( slots >= entries )
164 				return;
165 
166 			snooze( 1 );
167 		} while( system_time() - start_time < 1000000 );
168 
169 		LOG( di->si->log, _Radeon_WaitForFifo );
170 
171 		Radeon_ResetEngine( di );
172 	}
173 }
174 
175 // flush pixel cache of graphics card
176 void Radeon_FlushPixelCache( device_info *di )
177 {
178 	bigtime_t start_time;
179 
180 	OUTREGP( di->regs, RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL,
181 		~RADEON_RB2D_DC_FLUSH_ALL );
182 
183 	start_time = system_time();
184 
185 	do {
186 		if( (INREG( di->regs, RADEON_RB2D_DSTCACHE_CTLSTAT )
187 			 & RADEON_RB2D_DC_BUSY) == 0 )
188 			return;
189 
190 		snooze( 1 );
191 	} while( system_time() - start_time < 1000000 );
192 
193 	LOG( di->si->log, _Radeon_FlushPixelCache );
194 
195 	SHOW_ERROR0( 0, "pixel cache didn't become empty" );
196 }
197 
198 // reset graphics card's engine
199 // lock must be hold
200 void Radeon_ResetEngine( device_info *di )
201 {
202 	vuint8 *regs = di->regs;
203 	shared_info *si = di->si;
204 	uint32 clock_cntl_index, mclk_cntl, rbbm_soft_reset, host_path_cntl;
205 	uint32 cur_read_ptr;
206 
207 	SHOW_FLOW0( 3, "" );
208 
209 	Radeon_FlushPixelCache( di );
210 
211 	clock_cntl_index = INREG( regs, RADEON_CLOCK_CNTL_INDEX );
212 	R300_PLLFix( di->regs, di->asic );
213 
214 	// OUCH!
215 	// XFree disables any kind of automatic power power management
216 	// because of bugs of some ASIC revision (seems like the revisions
217 	// cannot be read out)
218 	// -> this is a very bad idea, especially when it comes to laptops
219 	// I comment it out for now, let's hope noone takes notice
220     if( di->num_crtc > 1 ) {
221 		Radeon_OUTPLLP( regs, di->asic, RADEON_SCLK_CNTL,
222 			RADEON_CP_MAX_DYN_STOP_LAT |
223 			RADEON_SCLK_FORCEON_MASK,
224 			~RADEON_DYN_STOP_LAT_MASK );
225 
226 /*		if( ai->si->asic == rt_rv200 ) {
227 		    Radeon_OUTPLLP( ai, RADEON_SCLK_MORE_CNTL,
228 		    	RADEON_SCLK_MORE_FORCEON, ~0 );
229 		}*/
230     }
231 
232 	mclk_cntl = Radeon_INPLL( regs, di->asic, RADEON_MCLK_CNTL );
233 
234 	// enable clock of units to be reset
235 	Radeon_OUTPLL( regs, di->asic, RADEON_MCLK_CNTL, mclk_cntl |
236       RADEON_FORCEON_MCLKA |
237       RADEON_FORCEON_MCLKB |
238       RADEON_FORCEON_YCLKA |
239       RADEON_FORCEON_YCLKB |
240       RADEON_FORCEON_MC |
241       RADEON_FORCEON_AIC );
242 
243 	// do the reset
244     host_path_cntl = INREG( regs, RADEON_HOST_PATH_CNTL );
245 	rbbm_soft_reset = INREG( regs, RADEON_RBBM_SOFT_RESET );
246 
247 	switch( di->asic ) {
248 	case rt_r300:
249 		OUTREG( regs, RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
250 			RADEON_SOFT_RESET_CP |
251 			RADEON_SOFT_RESET_HI |
252 			RADEON_SOFT_RESET_E2 |
253 			RADEON_SOFT_RESET_AIC ));
254 		INREG( regs, RADEON_RBBM_SOFT_RESET);
255 		OUTREG( regs, RADEON_RBBM_SOFT_RESET, 0);
256 		// this bit has no description
257 		OUTREGP( regs, RADEON_RB2D_DSTCACHE_MODE, (1 << 17), ~0 );
258 
259 		break;
260 	default:
261 		OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset |
262 			RADEON_SOFT_RESET_CP |
263 			RADEON_SOFT_RESET_HI |
264 			RADEON_SOFT_RESET_SE |
265 			RADEON_SOFT_RESET_RE |
266 			RADEON_SOFT_RESET_PP |
267 			RADEON_SOFT_RESET_E2 |
268 			RADEON_SOFT_RESET_RB |
269 			RADEON_SOFT_RESET_AIC );
270 		INREG( regs, RADEON_RBBM_SOFT_RESET );
271 		OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset &
272 			~( RADEON_SOFT_RESET_CP |
273 			RADEON_SOFT_RESET_HI |
274 			RADEON_SOFT_RESET_SE |
275 			RADEON_SOFT_RESET_RE |
276 			RADEON_SOFT_RESET_PP |
277 			RADEON_SOFT_RESET_E2 |
278 			RADEON_SOFT_RESET_RB |
279 			RADEON_SOFT_RESET_AIC ) );
280 		INREG( regs, RADEON_RBBM_SOFT_RESET );
281 	}
282 
283     OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET );
284     INREG( regs, RADEON_HOST_PATH_CNTL );
285     OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl );
286 
287 	// restore regs
288 	OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
289 
290 	OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
291 	R300_PLLFix( regs, di->asic );
292 	Radeon_OUTPLL( regs, di->asic, RADEON_MCLK_CNTL, mclk_cntl );
293 
294 	// reset ring buffer
295 	cur_read_ptr = INREG( regs, RADEON_CP_RB_RPTR );
296 	OUTREG( regs, RADEON_CP_RB_WPTR, cur_read_ptr );
297 
298 	//if( si->cp.ring.head ) {
299 	// during init, there are no feedback data
300 	if( si->cp.feedback.mem_handle != 0 ) {
301 		*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) =
302 			cur_read_ptr;
303 		//	*si->cp.ring.head = cur_read_ptr;
304 		si->cp.ring.tail = cur_read_ptr;
305 	}
306 
307 	++si->engine.count;
308 
309 	// mark all buffers as being finished
310 	Radeon_DiscardAllIndirectBuffers( di );
311 
312 	return;
313 }
314 
315 
316 // upload Micro-Code of CP
317 static void loadMicroEngineRAMData( device_info *di )
318 {
319 	int i;
320 	const uint32 (*microcode)[2];
321 
322 	SHOW_FLOW0( 3, "" );
323 
324 	switch( di->asic ) {
325 	case rt_r300:
326 	case rt_r300_4p:
327 	case rt_rv350:
328 	case rt_rv360:
329 	case rt_r350:
330 	case rt_r360:
331 		microcode = r300_cp_microcode;
332 		break;
333 	case rt_r200:
334 	//case rt_rv250:
335 	//case rt_m9:
336 		microcode = r200_cp_microcode;
337 		break;
338 	case rt_rs100:
339 	default:
340 		microcode = radeon_cp_microcode;
341 	}
342 
343 	Radeon_WaitForIdle( di, false, false );
344 
345 /*
346 	// HACK start
347 	Radeon_ResetEngine( di );
348 	OUTREG( di->regs, 0x30, 0x5133a3a0 );	// bus_cntl
349 	OUTREGP( di->regs, 0xf0c, 0xff00, ~0xff );	// latency
350 	Radeon_WaitForIdle( di, false, false );
351 	Radeon_ResetEngine( di );
352 	// HACK end
353 */
354 
355 	OUTREG( di->regs, RADEON_CP_ME_RAM_ADDR, 0 );
356 
357 	for ( i = 0 ; i < 256 ; i++ ) {
358 		OUTREG( di->regs, RADEON_CP_ME_RAM_DATAH, microcode[i][1] );
359 		OUTREG( di->regs, RADEON_CP_ME_RAM_DATAL, microcode[i][0] );
360 	}
361 }
362 
363 // aring_size - size of ring in dwords
364 static status_t initRingBuffer( device_info *di, int aring_size )
365 {
366 	status_t res;
367 	shared_info *si = di->si;
368 	CP_info *cp = &si->cp;
369 	vuint8 *regs = di->regs;
370 	int32 offset;
371 	memory_type_e memory_type;
372 
373 	memset( &cp->ring, 0, sizeof( cp->ring ));
374 
375 	// ring and indirect buffers can be either in AGP or PCI GART
376 	// (it seems that they cannot be in graphics memory, at least
377 	//  I had serious coherency problems when I tried that)
378 	memory_type = mt_nonlocal;
379 
380 	ALLOC_MEM( aring_size * 4, memory_type, true,
381 		&cp->ring.mem_handle, &offset );
382 
383 	if( res != B_OK ) {
384 		SHOW_ERROR0( 0, "Cannot allocate ring buffer" );
385 		return res;
386 	}
387 
388 	// setup CP buffer
389 	cp->ring.mem_type = memory_type;
390 	cp->ring.mem_offset = offset;
391 	cp->ring.vm_base = MEM2GC( memory_type, offset );
392 	cp->ring.size = aring_size;
393 	cp->ring.tail_mask = aring_size - 1;
394 	OUTREG( regs, RADEON_CP_RB_BASE, cp->ring.vm_base );
395 	SHOW_INFO( 3, "CP buffer address=%lx", cp->ring.vm_base );
396 
397 	// set ring buffer size
398 	// (it's log2 of qwords)
399 	OUTREG( regs, RADEON_CP_RB_CNTL, log2( cp->ring.size / 2 ));
400 	SHOW_INFO( 3, "CP buffer size mask=%d", log2( cp->ring.size / 2 ) );
401 
402 	// set write pointer delay to zero;
403 	// we assume that memory synchronization is done correctly my MoBo
404 	// and Radeon_SendCP contains a hack that hopefully fixes such problems
405 	OUTREG( regs, RADEON_CP_RB_WPTR_DELAY, 0 );
406 
407 	memset( MEM2CPU( cp->ring.mem_type, cp->ring.mem_offset), 0, cp->ring.size * 4 );
408 
409 	// set CP buffer pointers
410 	OUTREG( regs, RADEON_CP_RB_RPTR, 0 );
411 	OUTREG( regs, RADEON_CP_RB_WPTR, 0 );
412 	//*cp->ring.head = 0;
413 	cp->ring.tail = 0;
414 
415 	return B_OK;
416 }
417 
418 static void uninitRingBuffer( device_info *di )
419 {
420 	vuint8 *regs = di->regs;
421 
422 	// abort any activity
423 	Radeon_ResetEngine( di );
424 
425 	// disable CP BM
426 	OUTREG( regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
427 	// read-back for flushing
428 	INREG( regs, RADEON_CP_CSQ_CNTL );
429 
430 	FREE_MEM( mt_nonlocal, di->si->cp.ring.mem_handle );
431 }
432 
433 static status_t initCPFeedback( device_info *di )
434 {
435 	CP_info *cp = &di->si->cp;
436 	vuint8 *regs = di->regs;
437 	int32 offset;
438 	memory_type_e memory_type;
439 	status_t res;
440 
441 	// status information should be in PCI memory, so CPU can
442 	// poll it without locking the bus (PCI memory is the only
443 	// cachable memory available)
444 	memory_type = mt_PCI;
445 
446 	ALLOC_MEM( RADEON_SCRATCH_REG_OFFSET + 0x40, memory_type, true,
447 		&cp->feedback.mem_handle, &offset );
448 
449 	if( res != B_OK ) {
450 		SHOW_ERROR0( 0, "Cannot allocate buffers for status information" );
451 		return res;
452 	}
453 
454 	// setup CP read pointer buffer
455 	cp->feedback.mem_type = memory_type;
456 	cp->feedback.head_mem_offset = offset;
457 	cp->feedback.head_vm_address = MEM2GC( memory_type, cp->feedback.head_mem_offset );
458 	OUTREG( regs, RADEON_CP_RB_RPTR_ADDR, cp->feedback.head_vm_address );
459 	SHOW_INFO( 3, "CP read pointer buffer==%lx", cp->feedback.head_vm_address );
460 
461 	// setup scratch register buffer
462 	cp->feedback.scratch_mem_offset = offset + RADEON_SCRATCH_REG_OFFSET;
463 	cp->feedback.scratch_vm_start = MEM2GC( memory_type, cp->feedback.scratch_mem_offset );
464 	OUTREG( regs, RADEON_SCRATCH_ADDR, cp->feedback.scratch_vm_start );
465 	OUTREG( regs, RADEON_SCRATCH_UMSK, 0x3f );
466 
467 	*(uint32 *)MEM2CPU( cp->feedback.mem_type, cp->feedback.head_mem_offset) = 0;
468 	memset( MEM2CPU( cp->feedback.mem_type, cp->feedback.scratch_mem_offset), 0, 0x40 );
469 	//*cp->ring.head = 0;
470 
471 	return B_OK;
472 }
473 
474 static void uninitCPFeedback( device_info *di )
475 {
476 	vuint8 *regs = di->regs;
477 
478 	// don't allow any scratch buffer update
479 	OUTREG( regs, RADEON_SCRATCH_UMSK, 0x0 );
480 
481 	FREE_MEM( mt_PCI, di->si->cp.feedback.mem_handle );
482 }
483 
484 static status_t initIndirectBuffers( device_info *di )
485 {
486 	CP_info *cp = &di->si->cp;
487 	int32 offset;
488 	memory_type_e memory_type;
489 	int i;
490 	status_t res;
491 
492 	memory_type = mt_nonlocal;
493 
494 	ALLOC_MEM( NUM_INDIRECT_BUFFERS * INDIRECT_BUFFER_SIZE * 4, memory_type,
495 		true, &cp->buffers.mem_handle, &offset );
496 
497 	if( res != B_OK ) {
498 		SHOW_ERROR0( 0, "Cannot allocate indirect buffers" );
499 		return B_ERROR;
500 	}
501 
502 	cp->buffers.mem_type = memory_type;
503 	cp->buffers.mem_offset = offset;
504 	cp->buffers.vm_start = MEM2GC( memory_type, cp->buffers.mem_offset );
505 
506 	for( i = 0; i < NUM_INDIRECT_BUFFERS - 1; ++i ) {
507 		cp->buffers.buffers[i].next = i + 1;
508 	}
509 
510 	cp->buffers.buffers[i].next = -1;
511 
512 	cp->buffers.free_list = 0;
513 	cp->buffers.oldest = -1;
514 	cp->buffers.newest = -1;
515 	cp->buffers.active_state = -1;
516 	cp->buffers.cur_tag = 0;
517 
518 	memset( MEM2CPU( cp->buffers.mem_type, cp->buffers.mem_offset), 0,
519 		NUM_INDIRECT_BUFFERS * INDIRECT_BUFFER_SIZE * 4 );
520 
521 	return B_OK;
522 }
523 
524 static void uninitIndirectBuffers( device_info *di )
525 {
526 	FREE_MEM( mt_nonlocal, di->si->cp.buffers.mem_handle );
527 }
528 
529 // initialize CP so it's ready for BM
530 status_t Radeon_InitCP( device_info *di )
531 {
532 	thread_id thid;
533     thread_info thinfo;
534 	status_t res;
535 
536 	SHOW_FLOW0( 3, "" );
537 
538 	// this is _really_ necessary so functions like ResetEngine() know
539 	// that the CP is not set up yet
540 	memset( &di->si->cp, 0, sizeof( di->si->cp ));
541 
542 	if( (res = INIT_BEN( di->si->cp.lock, "Radeon CP" )) < 0 )
543 		return res;
544 
545 	// HACK: change owner of benaphore semaphore to team of calling thread;
546 	// reason: user code cannot acquire kernel semaphores, but the accelerant
547 	// is in user space; interestingly, it's enough to change the semaphore's
548 	// owner to _any_ non-system team (that's the only security check done by
549 	// the kernel)
550 	thid = find_thread( NULL );
551     get_thread_info( thid, &thinfo );
552     set_sem_owner( di->si->cp.lock.sem, thinfo.team );
553 
554 	// init raw CP
555 	loadMicroEngineRAMData( di );
556 
557 	// do soft-reset
558 	Radeon_ResetEngine( di );
559 
560 	// after warm-reset, the CP may still be active and thus react to
561 	// register writes during initialization unpredictably, so we better
562 	// stop it first
563 	OUTREG( di->regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
564 	INREG( di->regs, RADEON_CP_CSQ_CNTL );
565 
566 	// reset CP to make disabling active
567 	Radeon_ResetEngine( di );
568 
569 	res = initRingBuffer( di, CP_RING_SIZE );
570 	if( res < 0 )
571 		goto err4;
572 
573 	res = initCPFeedback( di );
574 	if( res < 0 )
575 		goto err3;
576 
577 	res = initIndirectBuffers( di );
578 	if( res < 0 )
579 		goto err2;
580 
581 	// tell CP to use BM
582 	Radeon_WaitForIdle( di, false, false );
583 
584 	// enable direct and indirect CP bus mastering
585 	OUTREG( di->regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM );
586 
587 	// allow bus mastering in general
588 	OUTREGP( di->regs, RADEON_BUS_CNTL, 0, ~RADEON_BUS_MASTER_DIS );
589 
590 	// don't allow mixing of 2D/3D/scratch/wait_until commands
591 	// (in fact, this doesn't seem to make any difference as we do a
592 	// manual sync in all these cases anyway)
593 	OUTREG( di->regs, RADEON_ISYNC_CNTL,
594 		RADEON_ISYNC_ANY2D_IDLE3D |
595 		RADEON_ISYNC_ANY3D_IDLE2D |
596 		RADEON_ISYNC_WAIT_IDLEGUI |
597 		RADEON_ISYNC_CPSCRATCH_IDLEGUI );
598 
599 	SHOW_FLOW( 3, "bus_cntl=%lx", INREG( di->regs, RADEON_BUS_CNTL ));
600 
601 	SHOW_FLOW0( 3, "Done" );
602 
603 	return B_OK;
604 
605 //err:
606 //	uninitIndirectBuffers( ai );
607 err2:
608 	uninitCPFeedback( di );
609 err3:
610 	uninitRingBuffer( di );
611 err4:
612 	DELETE_BEN( di->si->cp.lock );
613 	return res;
614 }
615 
616 
617 // shutdown CP, freeing any memory
618 void Radeon_UninitCP( device_info *di )
619 {
620 	vuint8 *regs = di->regs;
621 
622 	// abort any pending commands
623 	Radeon_ResetEngine( di );
624 
625 	// disable CP BM
626 	OUTREG( regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
627 	// read-back for flushing
628 	INREG( regs, RADEON_CP_CSQ_CNTL );
629 
630 	uninitRingBuffer( di );
631 	uninitCPFeedback( di );
632 	uninitIndirectBuffers( di );
633 
634 	DELETE_BEN( di->si->cp.lock );
635 }
636 
637 
638 // mark all indirect buffers as being free;
639 // this should only be called after a reset;
640 // lock must be hold
641 void Radeon_DiscardAllIndirectBuffers( device_info *di )
642 {
643 	CP_info *cp = &di->si->cp;
644 
645 	// during init, there is no indirect buffer
646 	if( cp->buffers.mem_handle == 0 )
647 		return;
648 
649 	// mark all sent indirect buffers as free
650 	while( cp->buffers.oldest != -1 ) {
651 		indirect_buffer *oldest_buffer =
652 			&cp->buffers.buffers[cp->buffers.oldest];
653 		int tmp_oldest_buffer;
654 
655 		SHOW_FLOW( 0, "%d", cp->buffers.oldest );
656 
657 		// remove buffer from "used" list
658 		tmp_oldest_buffer = oldest_buffer->next;
659 
660 		if( tmp_oldest_buffer == -1 )
661 			cp->buffers.newest = -1;
662 
663 		// put it on free list
664 		oldest_buffer->next = cp->buffers.free_list;
665 		cp->buffers.free_list = cp->buffers.oldest;
666 
667 		cp->buffers.oldest = tmp_oldest_buffer;
668 	}
669 }
670