⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cp_setup.c

📁 ati driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 2002, Thomas Kurschel		Part of Radeon accelerant			CP initialization/sync/cleanup.		It also handles command buffer synchronization.	non-local memory is used as following:	- 2048 dwords for ring buffer	- 253 indirect buffers a 4k (1024 dwords)	- 8 dwords for returned data (i.e. current read ptr)	  & 6 dwords for "scratch registers"	usage of scratch registers:	- reg 0 = reached engine.count	with a granularity of 4 KByte, we need 2+253+1=256 blocks, which is exactly 1 MB*/#include "radeon_driver.h"#include "CPMicroCode.h"#include "../shared/mmio.h"#include "../regs/cp_regs.h"#include "../regs/pll_regs.h"#include "../regs/rbbm_regs.h"#include "../regs/buscntrl_regs.h"#include "../common/utils.h"#include "../shared/pll_access.h"#include "log_coll.h"#include "shared/log_enum.h"#include <string.h>#if 0// macros for user-space#define ALLOC_MEM( asize, mem_type, aglobal, handle, offset ) \	{ \		radeon_alloc_mem am; \\		am.magic = RADEON_PRIVATE_DATA_MAGIC; \		am.size = (asize) * 4; \		am.memory_type = (mt_nonlocal); \		am.global = (aglobal); \\		res = ioctl( ai->fd, RADEON_ALLOC_MEM, &am ); \		if( res == B_OK ) \			*(handle) = am.handle; \			*(offset) = am.offset; \	}#define MEM2CPU( mem ) \	((uint32 *)(ai->mapped_memory[(mem).memory_type].data + (mem).offset))#define MEM2GC( mem ) ((mem).offset + si->memory[(mem).memory_type].virtual_addr_start)#define FREE_MEM( mem_type, handle ) \	{ \		radeon_free_mem fm; \\		fm.magic = RADEON_PRIVATE_DATA_MAGIC; \		fm.memory_type = mem_type; \		fm.handle = offset; \\		ioctl( ai->fd, RADEON_FREE_MEM, &fm ); \	}	#else// macros for kernel-space// allocate memory// if memory_type is non-local, it is replaced with default non-local type#define ALLOC_MEM( asize, mem_type, aglobal, handle, offset ) \	if( mem_type == mt_nonlocal ) \		mem_type = di->si->nonlocal_type; \	res = mem_alloc( di->memmgr[mem_type], asize, NULL, handle, offset );// get address as seen by program to access allocated memory// (memory_type must _not_ be non-local, see ALLOC_MEM)#define MEM2CPU( memory_type, offset ) \	((uint8 *)(memory_type == mt_local ? di->si->local_mem : \	(memory_type == mt_PCI ? di->pci_gart.buffer.ptr : di->agp_gart.buffer.ptr)) \	+ (offset))// get graphics card's virtual address of allocated memory// (memory_type must _not_ be non-local, see ALLOC_MEM)#define MEM2GC( memory_type, offset ) \	(di->si->memory[(memory_type)].virtual_addr_start + (offset))// free memory// if memory_type is non-local, it is replaced with default non-local type#define FREE_MEM( mem_type, handle ) \	mem_free( \		di->memmgr[ mem_type == mt_nonlocal ? di->si->nonlocal_type : mem_type], \		handle, NULL );	#endifvoid Radeon_DiscardAllIndirectBuffers( device_info *di );#define RADEON_SCRATCH_REG_OFFSET	32void Radeon_FlushPixelCache( device_info *di );// wait until engine is idle;// acquire_lock - 	true, if lock must be hold//					false, if lock is already acquired// keep_lock -		true, keep lock on exit (only valid if acquire_lock is true)void Radeon_WaitForIdle( device_info *di, bool acquire_lock, bool keep_lock ){	if( acquire_lock )		ACQUIRE_BEN( di->si->cp.lock );		Radeon_WaitForFifo( di, 64 );		while( 1 ) {		bigtime_t start_time = system_time();			do {			if( (INREG( di->regs, RADEON_RBBM_STATUS ) & RADEON_RBBM_ACTIVE) == 0 ) {				Radeon_FlushPixelCache( di );								if( acquire_lock && !keep_lock)					RELEASE_BEN( di->si->cp.lock );									return;			}						snooze( 1 );		} while( system_time() - start_time < 1000000 );				SHOW_ERROR( 3, "Engine didn't become idle (rbbm_status=%lx, cp_stat=%lx, tlb_address=%lx, tlb_data=%lx)",			INREG( di->regs, RADEON_RBBM_STATUS ),			INREG( di->regs, RADEON_CP_STAT ),			INREG( di->regs, RADEON_AIC_TLB_ADDR ),			INREG( di->regs, RADEON_AIC_TLB_DATA ));				LOG( di->si->log, _Radeon_WaitForIdle );		Radeon_ResetEngine( di );	}}// wait until "entries" FIFO entries are empty// lock must be holdvoid Radeon_WaitForFifo( device_info *di, int entries ){	while( 1 ) {		bigtime_t start_time = system_time();			do {			int slots = INREG( di->regs, RADEON_RBBM_STATUS ) & RADEON_RBBM_FIFOCNT_MASK;						if ( slots >= entries ) 				return;			snooze( 1 );		} while( system_time() - start_time < 1000000 );				LOG( di->si->log, _Radeon_WaitForFifo );				Radeon_ResetEngine( di );	}}// flush pixel cache of graphics cardvoid Radeon_FlushPixelCache( device_info *di ){	bigtime_t start_time;		OUTREGP( di->regs, RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL,		~RADEON_RB2D_DC_FLUSH_ALL );	start_time = system_time();		do {		if( (INREG( di->regs, RADEON_RB2D_DSTCACHE_CTLSTAT ) 			 & RADEON_RB2D_DC_BUSY) == 0 ) 			return;		snooze( 1 );	} while( system_time() - start_time < 1000000 );		LOG( di->si->log, _Radeon_FlushPixelCache );	SHOW_ERROR0( 0, "pixel cache didn't become empty" );}// reset graphics card's engine// lock must be holdvoid Radeon_ResetEngine( device_info *di ){	vuint8 *regs = di->regs;	shared_info *si = di->si;	uint32 clock_cntl_index, mclk_cntl, rbbm_soft_reset, host_path_cntl;	uint32 cur_read_ptr;		SHOW_FLOW0( 3, "" );	Radeon_FlushPixelCache( di );	clock_cntl_index = INREG( regs, RADEON_CLOCK_CNTL_INDEX );	R300_PLLFix( di->regs, di->asic );		// OUCH!	// XFree disables any kind of automatic power power management 	// because of bugs of some ASIC revision (seems like the revisions	// cannot be read out)	// -> this is a very bad idea, especially when it comes to laptops	// I comment it out for now, let's hope noone takes notice    if( di->num_crtc > 1 ) {		Radeon_OUTPLLP( regs, di->asic, RADEON_SCLK_CNTL, 			RADEON_CP_MAX_DYN_STOP_LAT |			RADEON_SCLK_FORCEON_MASK,			~RADEON_DYN_STOP_LAT_MASK );	/*		if( ai->si->asic == rt_rv200 ) {		    Radeon_OUTPLLP( ai, RADEON_SCLK_MORE_CNTL, 		    	RADEON_SCLK_MORE_FORCEON, ~0 );		}*/    }	mclk_cntl = Radeon_INPLL( regs, di->asic, RADEON_MCLK_CNTL );	// enable clock of units to be reset	Radeon_OUTPLL( regs, di->asic, RADEON_MCLK_CNTL, mclk_cntl |      RADEON_FORCEON_MCLKA |      RADEON_FORCEON_MCLKB |      RADEON_FORCEON_YCLKA |      RADEON_FORCEON_YCLKB |      RADEON_FORCEON_MC |      RADEON_FORCEON_AIC );	// do the reset    host_path_cntl = INREG( regs, RADEON_HOST_PATH_CNTL );	rbbm_soft_reset = INREG( regs, RADEON_RBBM_SOFT_RESET );	switch( di->asic ) {	case rt_r300:		OUTREG( regs, RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |			RADEON_SOFT_RESET_CP |			RADEON_SOFT_RESET_HI |			RADEON_SOFT_RESET_E2 |			RADEON_SOFT_RESET_AIC ));		INREG( regs, RADEON_RBBM_SOFT_RESET);		OUTREG( regs, RADEON_RBBM_SOFT_RESET, 0);		// this bit has no description		OUTREGP( regs, RADEON_RB2D_DSTCACHE_MODE, (1 << 17), ~0 );		break;	default:		OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset |			RADEON_SOFT_RESET_CP |			RADEON_SOFT_RESET_HI |			RADEON_SOFT_RESET_SE |			RADEON_SOFT_RESET_RE |			RADEON_SOFT_RESET_PP |			RADEON_SOFT_RESET_E2 |			RADEON_SOFT_RESET_RB |			RADEON_SOFT_RESET_AIC );		INREG( regs, RADEON_RBBM_SOFT_RESET );		OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset &			~( RADEON_SOFT_RESET_CP |			RADEON_SOFT_RESET_HI |			RADEON_SOFT_RESET_SE |			RADEON_SOFT_RESET_RE |			RADEON_SOFT_RESET_PP |			RADEON_SOFT_RESET_E2 |			RADEON_SOFT_RESET_RB |			RADEON_SOFT_RESET_AIC ) );		INREG( regs, RADEON_RBBM_SOFT_RESET );	}    OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET );    INREG( regs, RADEON_HOST_PATH_CNTL );    OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl );	// restore regs	OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);	OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );	R300_PLLFix( regs, di->asic );	Radeon_OUTPLL( regs, di->asic, RADEON_MCLK_CNTL, mclk_cntl );		// reset ring buffer	cur_read_ptr = INREG( regs, RADEON_CP_RB_RPTR );	OUTREG( regs, RADEON_CP_RB_WPTR, cur_read_ptr );		//if( si->cp.ring.head ) {	// during init, there are no feedback data	if( si->cp.feedback.mem_handle != 0 ) {		*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) = 			cur_read_ptr;		//	*si->cp.ring.head = cur_read_ptr;		si->cp.ring.tail = cur_read_ptr;	}	++si->engine.count;		// mark all buffers as being finished	Radeon_DiscardAllIndirectBuffers( di );	return;}// upload Micro-Code of CPstatic void loadMicroEngineRAMData( device_info *di ){	int i;	const uint32 (*microcode)[2];		SHOW_FLOW0( 3, "" );		switch( di->asic ) {	case rt_r300:	case rt_r300_4p:	case rt_rv350:	case rt_rv360:	case rt_r350:	case rt_r360:		microcode = r300_cp_microcode;		break;	case rt_r200:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -