aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-davinci/dma.c')
-rw-r--r--arch/arm/mach-davinci/dma.c105
1 files changed, 57 insertions, 48 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index f2e57d272958..648fbb760ae1 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -18,22 +18,13 @@
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/init.h> 21#include <linux/init.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/interrupt.h> 23#include <linux/interrupt.h>
25#include <linux/platform_device.h> 24#include <linux/platform_device.h>
26#include <linux/spinlock.h>
27#include <linux/compiler.h>
28#include <linux/io.h> 25#include <linux/io.h>
29 26
30#include <mach/cputype.h>
31#include <mach/memory.h>
32#include <mach/hardware.h>
33#include <mach/irqs.h>
34#include <mach/edma.h> 27#include <mach/edma.h>
35#include <mach/mux.h>
36
37 28
38/* Offsets matching "struct edmacc_param" */ 29/* Offsets matching "struct edmacc_param" */
39#define PARM_OPT 0x00 30#define PARM_OPT 0x00
@@ -509,43 +500,59 @@ static irqreturn_t dma_tc1err_handler(int irq, void *data)
509 return IRQ_HANDLED; 500 return IRQ_HANDLED;
510} 501}
511 502
512static int reserve_contiguous_params(int ctlr, unsigned int id, 503static int reserve_contiguous_slots(int ctlr, unsigned int id,
513 unsigned int num_params, 504 unsigned int num_slots,
514 unsigned int start_param) 505 unsigned int start_slot)
515{ 506{
516 int i, j; 507 int i, j;
517 unsigned int count = num_params; 508 unsigned int count = num_slots;
509 int stop_slot = start_slot;
510 DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
518 511
519 for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) { 512 for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) {
520 j = EDMA_CHAN_SLOT(i); 513 j = EDMA_CHAN_SLOT(i);
521 if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) 514 if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) {
515 /* Record our current beginning slot */
516 if (count == num_slots)
517 stop_slot = i;
518
522 count--; 519 count--;
520 set_bit(j, tmp_inuse);
521
523 if (count == 0) 522 if (count == 0)
524 break; 523 break;
525 else if (id == EDMA_CONT_PARAMS_FIXED_EXACT) 524 } else {
526 break; 525 clear_bit(j, tmp_inuse);
527 else 526
528 count = num_params; 527 if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
528 stop_slot = i;
529 break;
530 } else
531 count = num_slots;
532 }
529 } 533 }
530 534
531 /* 535 /*
532 * We have to clear any bits that we set 536 * We have to clear any bits that we set
533 * if we run out parameter RAMs, i.e we do find a set 537 * if we run out parameter RAM slots, i.e we do find a set
534 * of contiguous parameter RAMs but do not find the exact number 538 * of contiguous parameter RAM slots but do not find the exact number
535 * requested as we may reach the total number of parameter RAMs 539 * requested as we may reach the total number of parameter RAM slots
536 */ 540 */
537 if (count) { 541 if (i == edma_info[ctlr]->num_slots)
538 for (j = i - num_params + count + 1; j <= i ; ++j) 542 stop_slot = i;
543
544 for (j = start_slot; j < stop_slot; j++)
545 if (test_bit(j, tmp_inuse))
539 clear_bit(j, edma_info[ctlr]->edma_inuse); 546 clear_bit(j, edma_info[ctlr]->edma_inuse);
540 547
548 if (count)
541 return -EBUSY; 549 return -EBUSY;
542 }
543 550
544 for (j = i - num_params + 1; j <= i; ++j) 551 for (j = i - num_slots + 1; j <= i; ++j)
545 memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j), 552 memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
546 &dummy_paramset, PARM_SIZE); 553 &dummy_paramset, PARM_SIZE);
547 554
548 return EDMA_CTLR_CHAN(ctlr, i - num_params + 1); 555 return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
549} 556}
550 557
551/*-----------------------------------------------------------------------*/ 558/*-----------------------------------------------------------------------*/
@@ -743,26 +750,27 @@ EXPORT_SYMBOL(edma_free_slot);
743/** 750/**
744 * edma_alloc_cont_slots- alloc contiguous parameter RAM slots 751 * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
745 * The API will return the starting point of a set of 752 * The API will return the starting point of a set of
746 * contiguous PARAM's that have been requested 753 * contiguous parameter RAM slots that have been requested
747 * 754 *
748 * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT 755 * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
749 * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT 756 * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
750 * @count: number of contiguous Paramter RAM's 757 * @count: number of contiguous Paramter RAM slots
751 * @param - the start value of Parameter RAM that should be passed if id 758 * @slot - the start value of Parameter RAM slot that should be passed if id
752 * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT 759 * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
753 * 760 *
754 * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of 761 * 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 762 * contiguous Parameter RAM slots from parameter RAM 64 in the case of
756 * and 32 in the case of Primus 763 * DaVinci SOCs and 32 in the case of DA8xx SOCs.
757 * 764 *
758 * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a 765 * 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 766 * set of contiguous parameter RAM slots from the "slot" that is passed as an
760 * argument to the API. 767 * argument to the API.
761 * 768 *
762 * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries 769 * 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" 770 * starts looking for a set of contiguous parameter RAMs from the "slot"
764 * that is passed as an argument to the API. On failure the API will try to 771 * 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 772 * find a set of contiguous Parameter RAM slots from the remaining Parameter
773 * RAM slots
766 */ 774 */
767int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count) 775int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
768{ 776{
@@ -771,12 +779,13 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
771 * the number of channels and lesser than the total number 779 * the number of channels and lesser than the total number
772 * of slots 780 * of slots
773 */ 781 */
774 if (slot < edma_info[ctlr]->num_channels || 782 if ((id != EDMA_CONT_PARAMS_ANY) &&
775 slot >= edma_info[ctlr]->num_slots) 783 (slot < edma_info[ctlr]->num_channels ||
784 slot >= edma_info[ctlr]->num_slots))
776 return -EINVAL; 785 return -EINVAL;
777 786
778 /* 787 /*
779 * The number of parameter RAMs requested cannot be less than 1 788 * The number of parameter RAM slots requested cannot be less than 1
780 * and cannot be more than the number of slots minus the number of 789 * and cannot be more than the number of slots minus the number of
781 * channels 790 * channels
782 */ 791 */
@@ -786,11 +795,11 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
786 795
787 switch (id) { 796 switch (id) {
788 case EDMA_CONT_PARAMS_ANY: 797 case EDMA_CONT_PARAMS_ANY:
789 return reserve_contiguous_params(ctlr, id, count, 798 return reserve_contiguous_slots(ctlr, id, count,
790 edma_info[ctlr]->num_channels); 799 edma_info[ctlr]->num_channels);
791 case EDMA_CONT_PARAMS_FIXED_EXACT: 800 case EDMA_CONT_PARAMS_FIXED_EXACT:
792 case EDMA_CONT_PARAMS_FIXED_NOT_EXACT: 801 case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
793 return reserve_contiguous_params(ctlr, id, count, slot); 802 return reserve_contiguous_slots(ctlr, id, count, slot);
794 default: 803 default:
795 return -EINVAL; 804 return -EINVAL;
796 } 805 }
@@ -799,21 +808,21 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
799EXPORT_SYMBOL(edma_alloc_cont_slots); 808EXPORT_SYMBOL(edma_alloc_cont_slots);
800 809
801/** 810/**
802 * edma_free_cont_slots - deallocate DMA parameter RAMs 811 * edma_free_cont_slots - deallocate DMA parameter RAM slots
803 * @slot: first parameter RAM of a set of parameter RAMs to be freed 812 * @slot: first parameter RAM of a set of parameter RAM slots to be freed
804 * @count: the number of contiguous parameter RAMs to be freed 813 * @count: the number of contiguous parameter RAM slots to be freed
805 * 814 *
806 * This deallocates the parameter RAM slots allocated by 815 * This deallocates the parameter RAM slots allocated by
807 * edma_alloc_cont_slots. 816 * edma_alloc_cont_slots.
808 * Callers/applications need to keep track of sets of contiguous 817 * Callers/applications need to keep track of sets of contiguous
809 * parameter RAMs that have been allocated using the edma_alloc_cont_slots 818 * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
810 * API. 819 * API.
811 * Callers are responsible for ensuring the slots are inactive, and will 820 * Callers are responsible for ensuring the slots are inactive, and will
812 * not be activated. 821 * not be activated.
813 */ 822 */
814int edma_free_cont_slots(unsigned slot, int count) 823int edma_free_cont_slots(unsigned slot, int count)
815{ 824{
816 unsigned ctlr; 825 unsigned ctlr, slot_to_free;
817 int i; 826 int i;
818 827
819 ctlr = EDMA_CTLR(slot); 828 ctlr = EDMA_CTLR(slot);
@@ -826,11 +835,11 @@ int edma_free_cont_slots(unsigned slot, int count)
826 835
827 for (i = slot; i < slot + count; ++i) { 836 for (i = slot; i < slot + count; ++i) {
828 ctlr = EDMA_CTLR(i); 837 ctlr = EDMA_CTLR(i);
829 slot = EDMA_CHAN_SLOT(i); 838 slot_to_free = EDMA_CHAN_SLOT(i);
830 839
831 memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), 840 memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
832 &dummy_paramset, PARM_SIZE); 841 &dummy_paramset, PARM_SIZE);
833 clear_bit(slot, edma_info[ctlr]->edma_inuse); 842 clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse);
834 } 843 }
835 844
836 return 0; 845 return 0;