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: [email protected] > Cc: Paulraj, Sandeep > Subject: [PATCH] DaVinci: EDMA: Adding 2 new APIs for allocating/freeing > PARAMs > > From: Sandeep Paulraj <[email protected]> > > 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 <[email protected]> > --- > 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 _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
