Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 213765d7 authored by Sandeep Paulraj's avatar Sandeep Paulraj Committed by Kevin Hilman
Browse files

DaVinci: EDMA: Adding 2 new APIs for allocating/freeing PARAMs



For best performance, codecs often setup linked triggered
transfers with a contiguous block of params, and that is when
this API is used. Setup/configuration of these parameter RAMs
is most efficient if they are contiguous.
There is an API to allocate a set of contiguous parameter RAMs and
a corresponding API to free a set of contiguous parameter RAMs

Signed-off-by: default avatarSandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 0c30e0d3
Loading
Loading
Loading
Loading
+137 −0
Original line number Diff line number Diff line
@@ -509,6 +509,45 @@ static irqreturn_t dma_tc1err_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static int reserve_contiguous_params(int ctlr, unsigned int id,
				     unsigned int num_params,
				     unsigned int start_param)
{
	int i, j;
	unsigned int count = num_params;

	for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) {
		j = EDMA_CHAN_SLOT(i);
		if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse))
			count--;
			if (count == 0)
				break;
		else if (id == EDMA_CONT_PARAMS_FIXED_EXACT)
			break;
		else
			count = num_params;
	}

	/*
	 * We have to clear any bits that we set
	 * if we run out parameter RAMs, i.e we do find a set
	 * of contiguous parameter RAMs but do not find the exact number
	 * requested as we may reach the total number of parameter RAMs
	 */
	if (count) {
		for (j = i - num_params + count + 1; j <= i ; ++j)
			clear_bit(j, edma_info[ctlr]->edma_inuse);

		return -EBUSY;
	}

	for (j = i - num_params + 1; j <= i; ++j)
		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
			&dummy_paramset, PARM_SIZE);

	return EDMA_CTLR_CHAN(ctlr, i - num_params + 1);
}

/*-----------------------------------------------------------------------*/

/* Resource alloc/free:  dma channels, parameter RAM slots */
@@ -700,6 +739,104 @@ void edma_free_slot(unsigned slot)
}
EXPORT_SYMBOL(edma_free_slot);


/**
 * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
 * The API will return the starting point of a set of
 * contiguous PARAM's that have been requested
 *
 * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
 * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
 * @count: number of contiguous Paramter RAM's
 * @param  - the start value of Parameter RAM that should be passed if id
 * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
 *
 * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
 * contiguous Parameter RAMs from parameter RAM 64 in the case of DaVinci SOCs
 * and 32 in the case of Primus
 *
 * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
 * set of contiguous parameter RAMs from the "param" that is passed as an
 * argument to the API.
 *
 * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
 * starts looking for a set of contiguous parameter RAMs from the "param"
 * that is passed as an argument to the API. On failure the API will try to
 * find a set of contiguous Parameter RAMs in the remaining Parameter RAMs
 */
int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
{
	/*
	 * The start slot requested should be greater than
	 * the number of channels and lesser than the total number
	 * of slots
	 */
	if (slot < edma_info[ctlr]->num_channels ||
		slot >= edma_info[ctlr]->num_slots)
		return -EINVAL;

	/*
	 * The number of parameter RAMs requested cannot be less than 1
	 * and cannot be more than the number of slots minus the number of
	 * channels
	 */
	if (count < 1 || count >
		(edma_info[ctlr]->num_slots - edma_info[ctlr]->num_channels))
		return -EINVAL;

	switch (id) {
	case EDMA_CONT_PARAMS_ANY:
		return reserve_contiguous_params(ctlr, id, count,
						 edma_info[ctlr]->num_channels);
	case EDMA_CONT_PARAMS_FIXED_EXACT:
	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
		return reserve_contiguous_params(ctlr, id, count, slot);
	default:
		return -EINVAL;
	}

}
EXPORT_SYMBOL(edma_alloc_cont_slots);

/**
 * edma_free_cont_slots - deallocate DMA parameter RAMs
 * @slot: first parameter RAM of a set of parameter RAMs to be freed
 * @count: the number of contiguous parameter RAMs to be freed
 *
 * This deallocates the parameter RAM slots allocated by
 * edma_alloc_cont_slots.
 * Callers/applications need to keep track of sets of contiguous
 * parameter RAMs that have been allocated using the edma_alloc_cont_slots
 * API.
 * Callers are responsible for ensuring the slots are inactive, and will
 * not be activated.
 */
int edma_free_cont_slots(unsigned slot, int count)
{
	unsigned ctlr;
	int i;

	ctlr = EDMA_CTLR(slot);
	slot = EDMA_CHAN_SLOT(slot);

	if (slot < edma_info[ctlr]->num_channels ||
		slot >= edma_info[ctlr]->num_slots ||
		count < 1)
		return -EINVAL;

	for (i = slot; i < slot + count; ++i) {
		ctlr = EDMA_CTLR(i);
		slot = EDMA_CHAN_SLOT(i);

		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
			&dummy_paramset, PARM_SIZE);
		clear_bit(slot, edma_info[ctlr]->edma_inuse);
	}

	return 0;
}
EXPORT_SYMBOL(edma_free_cont_slots);

/*-----------------------------------------------------------------------*/

/* Parameter RAM operations (i) -- read/write partial slots */
+7 −0
Original line number Diff line number Diff line
@@ -226,6 +226,9 @@ enum sync_dimension {

#define EDMA_CHANNEL_ANY		-1	/* for edma_alloc_channel() */
#define EDMA_SLOT_ANY			-1	/* for edma_alloc_slot() */
#define EDMA_CONT_PARAMS_ANY		 1001
#define EDMA_CONT_PARAMS_FIXED_EXACT	 1002
#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003

/* alloc/free DMA channels and their dedicated parameter RAM slots */
int edma_alloc_channel(int channel,
@@ -237,6 +240,10 @@ void edma_free_channel(unsigned channel);
int edma_alloc_slot(unsigned ctlr, int slot);
void edma_free_slot(unsigned slot);

/* alloc/free a set of contiguous parameter RAM slots */
int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
int edma_free_cont_slots(unsigned slot, int count);

/* calls that operate on part of a parameter RAM slot */
void edma_set_src(unsigned slot, dma_addr_t src_port,
				enum address_mode mode, enum fifo_width);