diff options
author | Sandeep Paulraj <s-paulraj@ti.com> | 2009-07-27 15:10:36 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-08-26 04:55:59 -0400 |
commit | 213765d7b40a455ced8596edfa3cc51b5f69d515 (patch) | |
tree | 08f5ecd864b8c50263e2c35578165f0d895122c1 | |
parent | 0c30e0d31b57375b1decad4cc0e139e2f7758986 (diff) |
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: Sandeep Paulraj <s-paulraj@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-davinci/dma.c | 137 | ||||
-rw-r--r-- | 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 e6d7e6aca336..f2e57d272958 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) | |||
509 | return IRQ_HANDLED; | 509 | return IRQ_HANDLED; |
510 | } | 510 | } |
511 | 511 | ||
512 | static int reserve_contiguous_params(int ctlr, unsigned int id, | ||
513 | unsigned int num_params, | ||
514 | unsigned int start_param) | ||
515 | { | ||
516 | int i, j; | ||
517 | unsigned int count = num_params; | ||
518 | |||
519 | for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) { | ||
520 | j = EDMA_CHAN_SLOT(i); | ||
521 | if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) | ||
522 | count--; | ||
523 | if (count == 0) | ||
524 | break; | ||
525 | else if (id == EDMA_CONT_PARAMS_FIXED_EXACT) | ||
526 | break; | ||
527 | else | ||
528 | count = num_params; | ||
529 | } | ||
530 | |||
531 | /* | ||
532 | * We have to clear any bits that we set | ||
533 | * if we run out parameter RAMs, i.e we do find a set | ||
534 | * of contiguous parameter RAMs but do not find the exact number | ||
535 | * requested as we may reach the total number of parameter RAMs | ||
536 | */ | ||
537 | if (count) { | ||
538 | for (j = i - num_params + count + 1; j <= i ; ++j) | ||
539 | clear_bit(j, edma_info[ctlr]->edma_inuse); | ||
540 | |||
541 | return -EBUSY; | ||
542 | } | ||
543 | |||
544 | for (j = i - num_params + 1; j <= i; ++j) | ||
545 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), | ||
546 | &dummy_paramset, PARM_SIZE); | ||
547 | |||
548 | return EDMA_CTLR_CHAN(ctlr, i - num_params + 1); | ||
549 | } | ||
550 | |||
512 | /*-----------------------------------------------------------------------*/ | 551 | /*-----------------------------------------------------------------------*/ |
513 | 552 | ||
514 | /* Resource alloc/free: dma channels, parameter RAM slots */ | 553 | /* Resource alloc/free: dma channels, parameter RAM slots */ |
@@ -700,6 +739,104 @@ void edma_free_slot(unsigned slot) | |||
700 | } | 739 | } |
701 | EXPORT_SYMBOL(edma_free_slot); | 740 | EXPORT_SYMBOL(edma_free_slot); |
702 | 741 | ||
742 | |||
743 | /** | ||
744 | * edma_alloc_cont_slots- alloc contiguous parameter RAM slots | ||
745 | * The API will return the starting point of a set of | ||
746 | * contiguous PARAM's that have been requested | ||
747 | * | ||
748 | * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT | ||
749 | * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT | ||
750 | * @count: number of contiguous Paramter RAM's | ||
751 | * @param - the start value of Parameter RAM that should be passed if id | ||
752 | * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT | ||
753 | * | ||
754 | * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of | ||
755 | * contiguous Parameter RAMs from parameter RAM 64 in the case of DaVinci SOCs | ||
756 | * and 32 in the case of Primus | ||
757 | * | ||
758 | * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a | ||
759 | * set of contiguous parameter RAMs from the "param" that is passed as an | ||
760 | * argument to the API. | ||
761 | * | ||
762 | * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries | ||
763 | * starts looking for a set of contiguous parameter RAMs from the "param" | ||
764 | * that is passed as an argument to the API. On failure the API will try to | ||
765 | * find a set of contiguous Parameter RAMs in the remaining Parameter RAMs | ||
766 | */ | ||
767 | int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) | ||
768 | { | ||
769 | /* | ||
770 | * The start slot requested should be greater than | ||
771 | * the number of channels and lesser than the total number | ||
772 | * of slots | ||
773 | */ | ||
774 | if (slot < edma_info[ctlr]->num_channels || | ||
775 | slot >= edma_info[ctlr]->num_slots) | ||
776 | return -EINVAL; | ||
777 | |||
778 | /* | ||
779 | * The number of parameter RAMs requested cannot be less than 1 | ||
780 | * and cannot be more than the number of slots minus the number of | ||
781 | * channels | ||
782 | */ | ||
783 | if (count < 1 || count > | ||
784 | (edma_info[ctlr]->num_slots - edma_info[ctlr]->num_channels)) | ||
785 | return -EINVAL; | ||
786 | |||
787 | switch (id) { | ||
788 | case EDMA_CONT_PARAMS_ANY: | ||
789 | return reserve_contiguous_params(ctlr, id, count, | ||
790 | edma_info[ctlr]->num_channels); | ||
791 | case EDMA_CONT_PARAMS_FIXED_EXACT: | ||
792 | case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: | ||
793 | return reserve_contiguous_params(ctlr, id, count, slot); | ||
794 | default: | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | |||
798 | } | ||
799 | EXPORT_SYMBOL(edma_alloc_cont_slots); | ||
800 | |||
801 | /** | ||
802 | * edma_free_cont_slots - deallocate DMA parameter RAMs | ||
803 | * @slot: first parameter RAM of a set of parameter RAMs to be freed | ||
804 | * @count: the number of contiguous parameter RAMs to be freed | ||
805 | * | ||
806 | * This deallocates the parameter RAM slots allocated by | ||
807 | * edma_alloc_cont_slots. | ||
808 | * Callers/applications need to keep track of sets of contiguous | ||
809 | * parameter RAMs that have been allocated using the edma_alloc_cont_slots | ||
810 | * API. | ||
811 | * Callers are responsible for ensuring the slots are inactive, and will | ||
812 | * not be activated. | ||
813 | */ | ||
814 | int edma_free_cont_slots(unsigned slot, int count) | ||
815 | { | ||
816 | unsigned ctlr; | ||
817 | int i; | ||
818 | |||
819 | ctlr = EDMA_CTLR(slot); | ||
820 | slot = EDMA_CHAN_SLOT(slot); | ||
821 | |||
822 | if (slot < edma_info[ctlr]->num_channels || | ||
823 | slot >= edma_info[ctlr]->num_slots || | ||
824 | count < 1) | ||
825 | return -EINVAL; | ||
826 | |||
827 | for (i = slot; i < slot + count; ++i) { | ||
828 | ctlr = EDMA_CTLR(i); | ||
829 | slot = EDMA_CHAN_SLOT(i); | ||
830 | |||
831 | memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), | ||
832 | &dummy_paramset, PARM_SIZE); | ||
833 | clear_bit(slot, edma_info[ctlr]->edma_inuse); | ||
834 | } | ||
835 | |||
836 | return 0; | ||
837 | } | ||
838 | EXPORT_SYMBOL(edma_free_cont_slots); | ||
839 | |||
703 | /*-----------------------------------------------------------------------*/ | 840 | /*-----------------------------------------------------------------------*/ |
704 | 841 | ||
705 | /* Parameter RAM operations (i) -- read/write partial slots */ | 842 | /* 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 3c7dc2db70e4..eb8bfd7925e7 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 { | |||
226 | 226 | ||
227 | #define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ | 227 | #define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ |
228 | #define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ | 228 | #define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ |
229 | #define EDMA_CONT_PARAMS_ANY 1001 | ||
230 | #define EDMA_CONT_PARAMS_FIXED_EXACT 1002 | ||
231 | #define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003 | ||
229 | 232 | ||
230 | /* alloc/free DMA channels and their dedicated parameter RAM slots */ | 233 | /* alloc/free DMA channels and their dedicated parameter RAM slots */ |
231 | int edma_alloc_channel(int channel, | 234 | int edma_alloc_channel(int channel, |
@@ -237,6 +240,10 @@ void edma_free_channel(unsigned channel); | |||
237 | int edma_alloc_slot(unsigned ctlr, int slot); | 240 | int edma_alloc_slot(unsigned ctlr, int slot); |
238 | void edma_free_slot(unsigned slot); | 241 | void edma_free_slot(unsigned slot); |
239 | 242 | ||
243 | /* alloc/free a set of contiguous parameter RAM slots */ | ||
244 | int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count); | ||
245 | int edma_free_cont_slots(unsigned slot, int count); | ||
246 | |||
240 | /* calls that operate on part of a parameter RAM slot */ | 247 | /* calls that operate on part of a parameter RAM slot */ |
241 | void edma_set_src(unsigned slot, dma_addr_t src_port, | 248 | void edma_set_src(unsigned slot, dma_addr_t src_port, |
242 | enum address_mode mode, enum fifo_width); | 249 | enum address_mode mode, enum fifo_width); |