Message ID | 1248721836-25876-1-git-send-email-s-paulraj@ti.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
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
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 --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);