Exemple #1
0
/* Compile params part 1: generate template nodes */
static int fdma_compile1(struct fdma *fdma, struct stm_dma_params *params)
{
	struct stm_dma_params *this;

	for (this = params; this; this = this->next) {
		struct fdma_xfer_descriptor *desc = this->priv;

		if (desc != NULL)
			continue;

		desc = kzalloc(sizeof(struct fdma_xfer_descriptor),
				params->context);
		if (desc == NULL)
			return -ENOMEM;
		this->priv = desc;

		if (this->mode == MODE_SRC_SCATTER)
			desc->extrapolate_fn = fdma_extrapolate_sg_src;
		else if (this->mode == MODE_DST_SCATTER)
			desc->extrapolate_fn = fdma_extrapolate_sg_dst;
		else
			desc->extrapolate_fn = fdma_extrapolate_simple;

		if (this->mode == MODE_PACED)
			fdma_setup_paced_node(this, &desc->template_llu);
		else
			fdma_setup_freerunning_node(this, &desc->template_llu);

		/* For any 1D transfers, line_len = nbytes */
		desc->extrapolate_line_len = !((DIM_SRC(this->dim) == 2) ||
				(DIM_DST(this->dim) == 2));
	}

	return 0;
}
Exemple #2
0
static int fdma_setup_freerunning_node(struct stm_dma_params *params,
		struct fdma_llu_entry *llu)
{
	memset(llu, 0, sizeof(*llu));

	if (params->node_pause)
		llu->control |= SET_NODE_COMP_PAUSE | SET_NODE_COMP_IRQ;

	if (params->node_interrupt)
		llu->control |= SET_NODE_COMP_IRQ;

	if (DIM_SRC(params->dim) == 0)
		llu->control |= NODE_ADDR_STATIC << SOURCE_ADDR;
	else
		llu->control |= NODE_ADDR_INCR << SOURCE_ADDR;

	if (DIM_DST(params->dim) == 0)
		llu->control |= NODE_ADDR_STATIC << DEST_ADDR;
	else
		llu->control |= NODE_ADDR_INCR << DEST_ADDR;

	llu->line_len = params->line_len;
	llu->sstride = params->sstride;
	llu->dstride = params->dstride;
	return 0;
}
Exemple #3
0
static int fdma_setup_paced_node(struct stm_dma_params *params,
		struct fdma_llu_entry *llu)
{
	memset(llu, 0, sizeof(*llu));

	/* Moved this into the extrapolate functions so that we can
	 * change channel in the same way as address. Yech */
	/* llu->control = params->req_line; */
	llu->size_bytes = params->node_bytes;
	llu->line_len = params->node_bytes;

	if (params->node_pause)
		/* In order to recieve the pause interrupt
		 * we must also enable end of node interrupts. */
		llu->control |= SET_NODE_COMP_PAUSE | SET_NODE_COMP_IRQ;

	if (params->node_interrupt)
		llu->control |= SET_NODE_COMP_IRQ;

	if (DIM_SRC(params->dim) == 0)
		llu->control |= NODE_ADDR_STATIC << SOURCE_ADDR;
	else
		llu->control |= NODE_ADDR_INCR << SOURCE_ADDR;

	if (DIM_DST(params->dim) == 0)
		llu->control |= NODE_ADDR_STATIC << DEST_ADDR;
	else
		llu->control |= NODE_ADDR_INCR << DEST_ADDR;

	return 0;
}
Exemple #4
0
static struct fdma_llu_node *fdma_extrapolate_sg_dst(
		struct stm_dma_params *params,
		struct fdma_xfer_descriptor *desc,
		struct fdma_llu_node *llu_node)
{
	int i;
	struct scatterlist *sg = params->dstsg;
	struct fdma_llu_node *last_llu_node = llu_node;
	int offset = 0;

	for (i = 0; i < params->sglen; i++) {
		struct fdma_llu_entry *dest_llu = llu_node->virt_addr;

		dest_llu->control = desc->template_llu.control;
		dest_llu->size_bytes = sg_dma_len(sg);
		dest_llu->saddr	 = params->sar + offset;
		dest_llu->daddr	 = sg_dma_address(sg);
		if (desc->extrapolate_line_len)
			dest_llu->line_len = sg_dma_len(sg);
		else
			dest_llu->line_len = desc->template_llu.line_len;
		dest_llu->sstride = 0;
		dest_llu->dstride = desc->template_llu.dstride;

		if (DIM_SRC(params->dim) != 0)
			offset += sg_dma_len(sg);

		last_llu_node = llu_node++;
		dest_llu->next_item = llu_node->dma_addr;
		sg++;
	}

	return last_llu_node;
}