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

📄 scc.c

📁 uboot200903最新版本的通用uboot
💻 C
📖 第 1 页 / 共 2 页
字号:
static struct scc_dma_state scc_state_wr_39[] = { {0} };static struct scc_dma_state scc_state_rd_40[] = { {-1} };static struct scc_dma_state scc_state_wr_40[] = { {-1} };/* DMA state references to access from the driver */static struct scc_dma_state *scc_state_rd[] = {	scc_state_rd_0,	scc_state_rd_1,	scc_state_rd_2,	scc_state_rd_3,	scc_state_rd_4,	scc_state_rd_5,	scc_state_rd_6,	scc_state_rd_7,	scc_state_rd_8,	scc_state_rd_9,	scc_state_rd_10,	scc_state_rd_11,	scc_state_rd_12,	scc_state_rd_13,	scc_state_rd_14,	scc_state_rd_15,	scc_state_rd_16,	scc_state_rd_17,	scc_state_rd_18,	scc_state_rd_19,	scc_state_rd_20,	scc_state_rd_21,	scc_state_rd_22,	scc_state_rd_23,	scc_state_rd_24,	scc_state_rd_25,	scc_state_rd_26,	scc_state_rd_27,	scc_state_rd_28,	scc_state_rd_29,	scc_state_rd_30,	scc_state_rd_31,	scc_state_rd_32,	scc_state_rd_33,	scc_state_rd_34,	scc_state_rd_35,	scc_state_rd_36,	scc_state_rd_37,	scc_state_rd_38,	scc_state_rd_39,	scc_state_rd_40,};static struct scc_dma_state *scc_state_wr[] = {	scc_state_wr_0,	scc_state_wr_1,	scc_state_wr_2,	scc_state_wr_3,	scc_state_wr_4,	scc_state_wr_5,	scc_state_wr_6,	scc_state_wr_7,	scc_state_wr_8,	scc_state_wr_9,	scc_state_wr_10,	scc_state_wr_11,	scc_state_wr_12,	scc_state_wr_13,	scc_state_wr_14,	scc_state_wr_15,	scc_state_wr_16,	scc_state_wr_17,	scc_state_wr_18,	scc_state_wr_19,	scc_state_wr_20,	scc_state_wr_21,	scc_state_wr_22,	scc_state_wr_23,	scc_state_wr_24,	scc_state_wr_25,	scc_state_wr_26,	scc_state_wr_27,	scc_state_wr_28,	scc_state_wr_29,	scc_state_wr_30,	scc_state_wr_31,	scc_state_wr_32,	scc_state_wr_33,	scc_state_wr_34,	scc_state_wr_35,	scc_state_wr_36,	scc_state_wr_37,	scc_state_wr_38,	scc_state_wr_39,	scc_state_wr_40,};static u32 scc_takeover_mode = SCC_TO_IMMEDIATE;/* Change mode of the SPDMA for given direction */static u32 scc_agu_mode_sp = AGU_BYPASS;/* Change mode of the USB for given direction */static u32 scc_agu_mode_usb = AGU_BYPASS;static union scc_softwareconfiguration scc_software_configuration[SCC_MAX];static u32 dma_fsm[4][4] = {	/* DMA_CMD_RESET  DMA_CMD_SETUP    DMA_CMD_START    DMA_CMD_STOP */	/* DMA_STATE_RESET */	{DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_ERROR, DMA_STATE_ERROR},	/* DMA_STATE_SETUP */	{DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_START, DMA_STATE_SETUP},	/* DMA_STATE_START */	{DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_START, DMA_STATE_SETUP},	/* DMA_STATE_ERROR */	{DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_ERROR, DMA_STATE_ERROR},};static void dma_state_process(struct scc_dma_state *dma_state, u32 cmd){	dma_state->dma_status = dma_fsm[dma_state->dma_status][cmd];	dma_state->dma_cmd = cmd;}static void dma_state_process_dma_command(struct scc_dma_state *dma_state,					  u32 dma_cmd){	dma_state->dma_cmd = dma_cmd;	switch (dma_cmd) {	case DMA_START:	case DMA_START_FH_RESET:		dma_state_process(dma_state, DMA_CMD_START);		break;	case DMA_STOP:		dma_state_process(dma_state, DMA_CMD_STOP);		break;	default:		break;	}}static void scc_takeover_dma(enum scc_id id, u32 dma_id, u32 drs){	union scc_cmd dma_cmd;	dma_cmd.reg = 0;	/* Prepare the takeover for the DMA channel */	dma_cmd.bits.action = DMA_TAKEOVER;	dma_cmd.bits.id = dma_id;	dma_cmd.bits.rid = TO_DMA_CFG;	/* this is DMA_CFG register takeover */	if (drs == DMA_WRITE)		dma_cmd.bits.drs = DMA_WRITE;	reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);}int scc_dma_cmd(enum scc_id id, u32 cmd, u32 dma_id, u32 drs){	union scc_cmd dma_cmd;	struct scc_dma_state *dma_state;	if ((id >= SCC_MAX) || (id < 0))		return -EINVAL;	dma_cmd.reg = 0;	/* Prepare the takeover for the DMA channel */	dma_cmd.bits.action = cmd;	dma_cmd.bits.id = dma_id;	if (drs == DMA_WRITE) {		dma_cmd.bits.drs = DMA_WRITE;		dma_state = &scc_state_wr[id][dma_id];	} else {		dma_state = &scc_state_rd[id][dma_id];	}	dma_state->scc_id = id;	dma_state->dma_id = dma_id;	dma_state_process_dma_command(dma_state, cmd);	reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);	return 0;}int scc_set_usb_address_generation_mode(u32 agu_mode){	if (AGU_ACTIVE == agu_mode) {		/* Ensure both DMAs are stopped */		scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_WRITE);		scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_READ);	} else {		agu_mode = AGU_BYPASS;	}	scc_agu_mode_usb = agu_mode;	return 0;}int scc_setup_dma(enum scc_id id, u32 buffer_tag,		  u32 type, u32 fh_mode, u32 drs, u32 dma_id){	struct scc_dma_state *dma_state;	int return_value = 0;	union scc_dma_cfg dma_cfg;	u32 *buffer_tag_list = scc_descriptor_table[id].buffer_tag_list;	u32 tag_count, t, t_valid;	if ((id >= SCC_MAX) || (id < 0))		return -EINVAL;	/* if the register is only configured by hw, cannot write! */	if (1 == scc_descriptor_table[id].hw_dma_cfg)		return -EACCES;	if (DMA_WRITE == drs) {		if (dma_id >= scc_descriptor_table[id].p_dma_channels_wr)			return -EINVAL;		dma_state = &scc_state_wr[id][dma_id];	} else {		if (dma_id >= scc_descriptor_table[id].p_dma_channels_rd)			return -EINVAL;		dma_state = &scc_state_rd[id][dma_id];	}	/* Compose the DMA configuration register */	tag_count = buffer_tag_list[0];	t_valid = 0;	for (t = 1; t <= tag_count; t++) {		if (buffer_tag == buffer_tag_list[t]) {			/* Tag found - validate */			t_valid = 1;			break;		}	}	if (!t_valid)		return -EACCES;	/*	 * Read the register first -- two functions write into the register	 * it does not make sense to read the DMA config back, because there	 * are two register configuration sets (drs)	 */	dma_cfg.reg = 0;	dma_cfg.bits.buffer_id = buffer_tag;	dma_state_process(dma_state, DMA_CMD_SETUP);	/*	 * This is Packet CFG set select - usable for TSIO, EBI and those SCCs	 * which habe 2 packet configs	 */	dma_cfg.bits.packet_cfg_id =		scc_software_configuration[id].bits.packet_select;	if (type == DMA_CYCLIC)		dma_cfg.bits.buffer_type = 1;	else		dma_cfg.bits.buffer_type = 0;	if (fh_mode == USE_FH)		dma_cfg.bits.fh_mode = 1;	else		dma_cfg.bits.fh_mode = 0;	if (id == SCC_CPU1_SPDMA_RW)		dma_cfg.bits.agu_mode = scc_agu_mode_sp;	if (id == SCC_USB_RW)		dma_cfg.bits.agu_mode = scc_agu_mode_usb;	reg_write(SCC_DMA_CFG(scc_descriptor_table[id].base_address),		  dma_cfg.reg);	/* The DMA_CFG needs a takeover! */	if (SCC_TO_IMMEDIATE == scc_takeover_mode)		scc_takeover_dma(id, dma_id, drs);	/* if (buffer_tag is not used) */	dma_state->buffer_tag = buffer_tag;	dma_state->scc_id = id;	dma_state->dma_id = dma_id;	return return_value;}int scc_enable(enum scc_id id, u32 value){	if ((id >= SCC_MAX) || (id < 0))		return -EINVAL;	if (value == 0) {		scc_software_configuration[id].bits.enable_status = 0;	} else {		value = 1;		scc_software_configuration[id].bits.enable_status = 1;	}	reg_write(SCC_ENABLE(scc_descriptor_table[id].base_address), value);	return 0;}static inline void ehb(void){	__asm__ __volatile__(		"	.set	mips32r2	\n"		"	ehb			\n"		"	.set	mips0		\n");}int scc_reset(enum scc_id id, u32 value){	if ((id >= SCC_MAX) || (id < 0))		return -EINVAL;	/* Invert value to the strait logic from the negative hardware logic */	if (value == 0)		value = 1;	else		value = 0;	/* Write the value to the register */	reg_write(SCC_RESET(scc_descriptor_table[id].base_address), value);	/* sync flush */	asm("sync");	/* request bus write queue flush */	ehb();		/* wait until previous bus commit instr has finished */	asm("nop");	/* wait for flush to occur */	asm("nop");	/* wait for flush to occur */	udelay(100);	return 0;}

⌨️ 快捷键说明

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