diff mbox

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

Message ID 1248721836-25876-1-git-send-email-s-paulraj@ti.com (mailing list archive)
State Accepted
Headers show

Commit Message

s-paulraj@ti.com July 27, 2009, 7:10 p.m. UTC
From: Sandeep Paulraj <s-paulraj@ti.com>

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: Sandeep Paulraj <s-paulraj@ti.com>
---
 arch/arm/mach-davinci/dma.c               |  137 +++++++++++++++++++++++++++++
 arch/arm/mach-davinci/include/mach/edma.h |    7 ++
 2 files changed, 144 insertions(+), 0 deletions(-)

Comments

s-paulraj@ti.com Aug. 25, 2009, 1:46 p.m. UTC | #1
Kevin,

I see that you have reviewed all my patches except this one. Maybe you just missed it?

Thanks,
Sandeep

> -----Original Message-----
> From: Paulraj, Sandeep
> Sent: Monday, July 27, 2009 3:11 PM
> To: davinci-linux-open-source@linux.davincidsp.com
> Cc: Paulraj, Sandeep
> Subject: [PATCH] DaVinci: EDMA: Adding 2 new APIs for allocating/freeing
> PARAMs
> 
> From: Sandeep Paulraj <s-paulraj@ti.com>
> 
> 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: Sandeep Paulraj <s-paulraj@ti.com>
> ---
>  arch/arm/mach-davinci/dma.c               |  137
> +++++++++++++++++++++++++++++
>  arch/arm/mach-davinci/include/mach/edma.h |    7 ++
>  2 files changed, 144 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
> index e6d7e6a..f2e57d2 100644
> --- a/arch/arm/mach-davinci/dma.c
> +++ b/arch/arm/mach-davinci/dma.c
> @@ -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 */
> diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-
> davinci/include/mach/edma.h
> index 3c7dc2d..b96b2f4 100644
> --- a/arch/arm/mach-davinci/include/mach/edma.h
> +++ b/arch/arm/mach-davinci/include/mach/edma.h
> @@ -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);
> --
> 1.6.0.4
Kevin Hilman Aug. 25, 2009, 3:06 p.m. UTC | #2
s-paulraj@ti.com writes:

> From: Sandeep Paulraj <s-paulraj@ti.com>
>
> 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: Sandeep Paulraj <s-paulraj@ti.com>

Looks fine, minor whitespace problem below that I'll fix when committing.

[...]

>  /* Parameter RAM operations (i) -- read/write partial slots */
> diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
> index 3c7dc2d..b96b2f4 100644
> --- a/arch/arm/mach-davinci/include/mach/edma.h
> +++ b/arch/arm/mach-davinci/include/mach/edma.h
> @@ -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

stray tab here

Kevin
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index e6d7e6a..f2e57d2 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -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 */
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
index 3c7dc2d..b96b2f4 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -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);