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

📄 dma.c

📁 TI达芬奇 arm+dsp双核平台Davinci 6446 EVM板的linux下的 处理器平台底层代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				}				dev_dbg(&edma_dev.dev, "param_no=%d\r\n",					dma_chan[*lch].param_no);				if (dma_chan[*lch].param_no >=				    DAVINCI_EDMA_NUM_DMACH				    &&				    dma_chan[*lch].param_no <				    (DAVINCI_EDMA_NUM_DMACH +				     DAVINCI_EDMA_NUM_QDMACH)				    ) {					ptr_edmacc_regs->qrae[0] =					    ptr_edmacc_regs->qrae[0] |					    (1 << (dma_chan[*lch].param_no -						   DAVINCI_EDMA_NUM_DMACH));				} else {					if (dma_chan[*lch].param_no < 32) {						ptr_edmacc_regs->dra[0].drae =						    ptr_edmacc_regs->dra[0].drae						    |						    (1 << dma_chan[*lch].						     param_no);					} else {						ptr_edmacc_regs->dra[0].draeh =						    ptr_edmacc_regs->dra[0].						    draeh | (1 <<							     (dma_chan[*lch].							      param_no - 32));					}				}				if (callback) {					dma_chan[*lch].tcc =					    request_dma_interrupt(*lch,								  callback,								  data,								  dma_chan								  [*lch].								  param_no,								  *tcc);					if (dma_chan[*lch].tcc == -1) {						return -EINVAL;					} else {						*tcc = dma_chan[*lch].tcc;					}				} else {					dma_chan[*lch].tcc = -1;				}				map_dmach_queue(dev_id, eventq_no);				ret_val = 0;				break;			}			i++;		}	}	else if (dev_id == DAVINCI_EDMA_PARAM_ANY) {		ret_val = 0;		for (i = (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH);		     i < DAVINCI_EDMA_NUM_PARAMENTRY; i++) {			if (!dma_chan[i].in_use) {				dev_dbg(&edma_dev.dev, "any link = %d\r\n", i);				*lch = i;				dma_chan[*lch].param_no =				    request_param(*lch, dev_id);				if (dma_chan[*lch].param_no == -1) {					dev_dbg(&edma_dev.dev,						"request_param failed\r\n");					return -EINVAL;				} else {					dev_dbg(&edma_dev.dev, "param_no=%d\r\n",						dma_chan[*lch].param_no);				}				if (*tcc != -1)					dma_chan[*lch].tcc = *tcc;				else					dma_chan[*lch].tcc = -1;				ret_val = 0;				break;			}		}	} else {		ret_val = -EINVAL;	}	if (!ret_val) {		if (dev_id >= DAVINCI_EDMA_NUM_DMACH && dev_id <		    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {			/* Master Channel */			qdam_to_param_mapping[dev_id -					      DAVINCI_EDMA_NUM_DMACH] =			    dma_chan[*lch].param_no;			LOCK;			/* It's used global data structure and used to find out			   whether channel is available or not */			dma_chan[qdam_to_param_mapping				 [dev_id - DAVINCI_EDMA_NUM_DMACH]].in_use = 1;			UNLOCK;			dma_chan[qdam_to_param_mapping				 [dev_id - DAVINCI_EDMA_NUM_DMACH]].dev_id =			    *lch;			dma_chan[qdam_to_param_mapping				 [dev_id - DAVINCI_EDMA_NUM_DMACH]].tcc =			    dma_chan[*lch].tcc;			temp_ch =			    qdam_to_param_mapping[dev_id -						  DAVINCI_EDMA_NUM_DMACH];			dma_chan[temp_ch].param_no = dma_chan[*lch].param_no;			if (dma_chan[*lch].tcc != -1) {				ptr_edmacc_regs->paramentry[dma_chan[temp_ch].							    param_no].opt &=				    (~TCC);				ptr_edmacc_regs->paramentry[dma_chan[temp_ch].							    param_no].opt |=				    ((0x3f & dma_chan[*lch].tcc) << 12);				/* set TCINTEN bit in PARAM entry */				ptr_edmacc_regs->				    paramentry[dma_chan[temp_ch].param_no].				    opt |= TCINTEN;			} else {				ptr_edmacc_regs->paramentry[dma_chan[temp_ch].							    param_no].opt &=				    ~TCINTEN;			}			/* assign the link field to no link. i.e 0xffff */			ptr_edmacc_regs->paramentry[dma_chan[temp_ch].						    param_no].			    link_bcntrld |= 0xffff;		} else {			/* Slave Channel */			LOCK;			/* Global structure to identify whether resoures is			   available or not */			dma_chan[*lch].in_use = 1;			UNLOCK;			dma_chan[*lch].dev_id = *lch;			if (dma_chan[*lch].tcc != -1) {				ptr_edmacc_regs->paramentry[dma_chan[*lch].							    param_no].opt &=				    (~TCC);				ptr_edmacc_regs->paramentry[dma_chan[*lch].							    param_no].opt |=				    ((0x3f & dma_chan[*lch].tcc) << 12);				/* set TCINTEN bit in PARAM entry */				ptr_edmacc_regs->paramentry[dma_chan[*lch].							    param_no].opt |=				    TCINTEN;			} else {				ptr_edmacc_regs->paramentry[dma_chan[*lch].							    param_no].opt &=				    ~TCINTEN;			}			/* assign the link field to no link. i.e 0xffff */			ptr_edmacc_regs->paramentry[dma_chan[*lch].						    param_no].			    link_bcntrld |= 0xffff;		}	}	return ret_val;}/****************************************************************************** * * DMA channel free: Free dma channle * Arguments: *      dev_id     - request for the param entry device id * * Return: zero on success, or corresponding error no on failure * *****************************************************************************/void davinci_free_dma(int lch){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	LOCK;	dma_chan[lch].in_use = 0;	UNLOCK;	free_param(dma_chan[lch].param_no);	if (lch >= 0	    && lch < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		free_dma_interrupt(dma_chan[lch].tcc);	}}/****************************************************************************** * * DMA source parameters setup * ARGUMENTS: *      lch         - channel for which the source parameters to be configured *      src_port    - Source port address *      addressMode - indicates wether addressing mode is fifo. * *****************************************************************************/void davinci_set_dma_src_params(int lch, unsigned long src_port,				enum address_mode mode, enum fifo_width width){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		/* set the source port address		   in source register of param structure */		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src =		    src_port;		/* set the fifo addressing mode */		if (mode) {	/* reset SAM and FWID */			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    &= (~(SAM | EDMA_FWID));			/* set SAM and program FWID */			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    |= (mode | ((width & 0x7) << 8));		}	}}/****************************************************************************** * * DMA destination parameters setup * ARGUMENTS: *    lch - channel or param device for destination parameters to be configured *    dest_port    - Destination port address *    addressMode  - indicates wether addressing mode is fifo. * *****************************************************************************/void davinci_set_dma_dest_params(int lch, unsigned long dest_port,				 enum address_mode mode, enum fifo_width width){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		/* set the destination port address		   in dest register of param structure */		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].dst =		    dest_port;		/* set the fifo addressing mode */		if (mode) {	/* reset DAM and FWID */			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    &= (~(DAM | EDMA_FWID));			/* set DAM and program FWID */			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    |= ((mode << 1) | ((width & 0x7) << 8));		}	}}/****************************************************************************** * * DMA source index setup * ARGUMENTS: *      lch     - channel or param device for configuration of source index *      srcbidx - source B-register index *      srccidx - source C-register index * *****************************************************************************/void davinci_set_dma_src_index(int lch, short src_bidx, short src_cidx){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx		    &= 0xffff0000;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx		    |= src_bidx;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx		    &= 0xffff0000;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx		    |= src_cidx;	}}/****************************************************************************** * * DMA destination index setup * ARGUMENTS: *      lch    - channel or param device for configuration of destination index *      srcbidx - dest B-register index *      srccidx - dest C-register index * *****************************************************************************/void davinci_set_dma_dest_index(int lch, short dest_bidx, short dest_cidx){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx		    &= 0x0000ffff;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx		    |= ((unsigned long)dest_bidx << 16);		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx		    &= 0x0000ffff;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx		    |= ((unsigned long)dest_cidx << 16);	}}/****************************************************************************** * * DMA transfer parameters setup * ARGUMENTS: *      lch  - channel or param device for configuration of aCount, bCount and *         cCount regs. *      acnt - acnt register value to be configured *      bcnt - bcnt register value to be configured *      ccnt - ccnt register value to be configured * *****************************************************************************/void davinci_set_dma_transfer_params(int lch, unsigned short acnt,				     unsigned short bcnt, unsigned short ccnt,				     unsigned short bcntrld,				     enum sync_dimension sync_mode){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].link_bcntrld		    &= 0x0000ffff;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].link_bcntrld		    |= (bcntrld << 16);		if (sync_mode == ASYNC)			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    &= (~SYNCDIM);		else			ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt			    |= SYNCDIM;		/* Set the acount, bcount, ccount registers */		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].a_b_cnt =		    (bcnt << 16) | acnt;		ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].ccnt = ccnt;	}}/****************************************************************************** * * davinci_set_dma_params - * ARGUMENTS: *      lch - logical channel number * *****************************************************************************/void davinci_set_dma_params(int lch, edmacc_paramentry_regs * temp){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		memcpy((void *)		       &(ptr_edmacc_regs->			 paramentry[dma_chan[lch].param_no].opt),		       (void *)temp, sizeof(edmacc_paramentry_regs));	}}/****************************************************************************** * * davinci_get_dma_params - * ARGUMENTS: *      lch - logical channel number * *****************************************************************************/void davinci_get_dma_params(int lch, edmacc_paramentry_regs * temp){	int temp_ch = 0;	if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <	    (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {		temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];		lch = temp_ch;	}	if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {		memcpy((void *)temp,		       (void *)&(ptr_edmacc_regs->				 paramentry[dma_chan[lch].param_no].opt),		       sizeof(edmacc_paramentry_regs));	}}/****************************************************************************** * * DMA Strat - Starts the dma on the channel passed * ARGUMENTS: *      lch - logical channel number * *****************************************************************************/int davinci_start_dma(int lch){	int ret_val;	if (lch >= 0 && (lch < DAVINCI_EDMA_NUM_DMACH)) {		int i = 0;		int flag = 0;		/* If the dma start request is for the unused events */		while (dma_chan_no_event[i] != -1) {			if (dma_chan_no_event[i] == lch) {				/* EDMA channels without event association */				dev_dbg(&edma_dev.dev, "ESR=%x\r\n",					ptr_edmacc_regs->shadow[0].esr);				(lch < 32) ?				    (ptr_edmacc_regs->shadow[0].esr |=				     (1UL << lch)) : (ptr_edmacc_regs->						      shadow[0].esrh |=						      (1UL << (lch - 32)));				flag = 1;				ret_val = 0;				break;			}			i++;		}		if (!flag) {			/* EDMA channel with event association */

⌨️ 快捷键说明

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