Exemple #1
0
/**
 * sw_dma_request - request a dma channel
 * @name:	dma channel name
 * @type:	channel type, normal or dedicate
 *
 * Returns handle to the channel if success, NULL if failed.
 */
dma_hdl_t sw_dma_request(char * name, dma_chan_type_e type)
{
	u32 i, num;
	u32 usign = 0;
	dma_channel_t *pchan = NULL;

	DMA_DBG("%s: name %s, chan type %d\n", __func__, name, (u32)type);
	if((name && strlen(name) >= MAX_NAME_LEN) || (type != CHAN_NORMAL && type != CHAN_DEDICATE)) {
		DMA_ERR("%s: para err, name %s, type %d\n", __func__, name, (u32)type);
		return NULL;
	}

	mutex_lock(&dma_mutex);
	/* check if already exist */
	if(NULL != name && __dma_channel_already_exist(name)) {
		usign = __LINE__;
		goto end;
	}
	/* get a free channel */
	if(CHAN_NORMAL == type)
		i = 0;
	else
		i = 8;
	num = i + 8;
	for(; i < num ; i++) {
		if(0 == g_dma_mgr.chnl[i].used) {
			WARN_ON(!__chan_is_free(&g_dma_mgr.chnl[i]));
			break;
		}
	}
	if(num == i) {
		usign = __LINE__;
		goto end;
	}

	/* init channel */
	pchan = &g_dma_mgr.chnl[i];
	pchan->used = 1;
	dma_request_init(pchan);
	if(NULL != name)
		strcpy(pchan->owner, name);

end:
	mutex_unlock(&dma_mutex);
	if(0 != usign)
		DMA_ERR("%s err, line %d\n", __func__, usign);
	else
		DMA_DBG("%s: success, channel id %d\n", __func__, i);
	return (dma_hdl_t)pchan;
}
/**
 * sw_dma_getposition - get the src and dst address from the reg
 * @dma_hdl:	dma handle
 * @psrc:	pointed to src addr that will be got
 * @pdst:	pointed to dst addr that will be got
 *
 * Returns 0 if sucess, the err line number if failed.
 */
int sw_dma_getposition(dm_hdl_t dma_hdl, u32 *psrc, u32 *pdst)
{
	dma_channel_t *pchan = (dma_channel_t *)dma_hdl;

	if(NULL == dma_hdl || NULL == psrc || NULL == pdst) {
		DMA_ERR("%s err, line %d\n", __func__, __LINE__);
		return __LINE__;
	}
	if(0 == pchan->used) {
		DMA_ERR("%s err, line %d\n", __func__, __LINE__);
		return __LINE__;
	}

	*psrc = csp_dma_chan_get_cur_srcaddr(pchan);
	*pdst = csp_dma_chan_get_cur_dstaddr(pchan);
	DMA_DBG("%s: get *psrc 0x%08x, *pdst 0x%08x\n", __func__, *psrc, *pdst);
	return 0;
}
Exemple #3
0
/**
 * sw_dma_getposition - get src and dst position
 * @dma_hdl:	dma handle
 * @psrc:	stored the src addr got
 * @pdst:	stored the dst addr got
 *
 * Returns 0 if sucess, otherwise failed
 */
int sw_dma_getposition(dma_hdl_t dma_hdl, u32 *psrc, u32 *pdst)
{
	dma_channel_t *pchan = (dma_channel_t *)dma_hdl;
	unsigned long flags;
	u32 saddr, daddr, reamin;

	BUG_ON(unlikely(!dma_handle_is_valid(dma_hdl)));
	BUG_ON(unlikely(NULL == psrc || NULL == pdst));

	DMA_CHAN_LOCK(&pchan->lock, flags);
	/* get src/dst start addr */
	saddr = csp_dma_get_saddr(pchan);
	daddr = csp_dma_get_daddr(pchan);
	/* get remain bytes */
	reamin = csp_dma_get_bcnt(pchan);
	/* note: tha caller use "period - reamin" to get transferred bytes */
	*psrc = saddr - reamin;
	*pdst = daddr - reamin;
	DMA_CHAN_UNLOCK(&pchan->lock, flags);
	DMA_DBG("%s: get *psrc 0x%08x, *pdst 0x%08x\n", __func__, *psrc, *pdst);
	return 0;
}
/**
 * sw_dma_request - request a dma channel
 * @name:	dma channel name
 *
 * Returns handle to the channel if success, NULL if failed.
 */
dm_hdl_t sw_dma_request(char *name, enum dma_work_mode_e work_mode)
{
	u32	i = 0;
	u32	usign = 0;
	dma_channel_t *pchan = NULL;

	DMA_DBG("%s: name %s, work_mode %d\n", __func__, name, (u32)work_mode);
	if(strlen(name) >= MAX_OWNER_NAME_LEN || (work_mode != DMA_WORK_MODE_CHAIN && work_mode != DMA_WORK_MODE_SINGLE)) {
		DMA_ERR("%s: para err, name %s, work mode %d\n", __func__, name, (u32)work_mode);
		return NULL;
	}

	mutex_lock(&dma_mutex);

	/* check if already exist */
	if(NULL != name && __dma_channel_already_exist(name)) {
		usign = __LINE__;
		goto end;
	}
	/* get a free channel */
	for(i = 0; i < DMA_CHAN_TOTAL; i++) {
		pchan = &dma_chnl[i];
		if(0 == pchan->used) {
#ifdef DBG_DMA
			if(true != __dma_check_channel_free(pchan))
				DMA_ERR("%s(%d) err, channel is not free\n", __func__, __LINE__);
#endif /* DBG_DMA */
			break;
		}
	}
	/* cannot get a free channel */
	if(DMA_CHAN_TOTAL == i) {
		usign = __LINE__;
		goto end;
	}

	/* init channel */
	if(DMA_WORK_MODE_CHAIN == work_mode) {
		dma_request_init_chain(pchan);
	} else if(DMA_WORK_MODE_SINGLE == work_mode) {
		dma_request_init_single(pchan);
#ifdef NOT_ALLOC_DES_TEMP
		v_addr = (u32)dma_alloc_coherent(NULL, TEMP_DES_CNT * sizeof(des_item), (dma_addr_t *)&p_addr, GFP_KERNEL);
		if(0 == v_addr)
			printk("%s err, dma_alloc_coherent failed, line %d\n", __func__, __LINE__);
		else
			printk("%s: dma_alloc_coherent return v_addr 0x%08x, p_addr 0x%08x\n", __func__, v_addr, p_addr);
		index_get = 0;
		index_put = 0;
#endif /* NOT_ALLOC_DES_TEMP */
	}
	pchan->used = 1;
	if(NULL != name)
		strcpy(pchan->owner, name);
	pchan->work_mode = work_mode;

end:
	mutex_unlock(&dma_mutex);
	if(0 != usign) {
		DMA_ERR("%s err, line %d\n", __func__, usign);
		return (dm_hdl_t)NULL;
	} else {
		DMA_DBG("%s: success, channel id %d\n", __func__, i);
		return (dm_hdl_t)pchan;
	}
}
/**
 * __dma_dump_config_para - dump dma_config_t struct
 * @para:	dma_config_t struct to dump
 */
static void __dma_dump_config_para(struct dma_config_t *para)
{
	if(NULL == para) {
		DMA_ERR("%s err, line %d\n", __func__, __LINE__);
		return;
	}

	DMA_DBG("+++++++++++%s+++++++++++\n", __func__);
	DMA_DBG("  xfer_type:         %d\n", para->xfer_type);
	DMA_DBG("  address_type:      %d\n", para->address_type);
	DMA_DBG("  para:              0x%08x\n", para->para);
	DMA_DBG("  irq_spt:           %d\n", para->irq_spt);
	DMA_DBG("  src_addr:          0x%08x\n", para->src_addr);
	DMA_DBG("  dst_addr:          0x%08x\n", para->dst_addr);
	DMA_DBG("  byte_cnt:          0x%08x\n", para->byte_cnt);
	DMA_DBG("  bconti_mode:       %d\n", para->bconti_mode);
	DMA_DBG("  src_drq_type:      %d\n", para->src_drq_type);
	DMA_DBG("  dst_drq_type:      %d\n", para->dst_drq_type);
	DMA_DBG("-----------%s-----------\n", __func__);
}