diff options
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r-- | arch/arm/plat-omap/dma.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index fd3154ae69b1..68eaae324b6a 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -691,13 +691,16 @@ static inline void disable_lnk(int lch) | |||
691 | static inline void omap2_enable_irq_lch(int lch) | 691 | static inline void omap2_enable_irq_lch(int lch) |
692 | { | 692 | { |
693 | u32 val; | 693 | u32 val; |
694 | unsigned long flags; | ||
694 | 695 | ||
695 | if (!cpu_class_is_omap2()) | 696 | if (!cpu_class_is_omap2()) |
696 | return; | 697 | return; |
697 | 698 | ||
699 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
698 | val = dma_read(IRQENABLE_L0); | 700 | val = dma_read(IRQENABLE_L0); |
699 | val |= 1 << lch; | 701 | val |= 1 << lch; |
700 | dma_write(val, IRQENABLE_L0); | 702 | dma_write(val, IRQENABLE_L0); |
703 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
701 | } | 704 | } |
702 | 705 | ||
703 | int omap_request_dma(int dev_id, const char *dev_name, | 706 | int omap_request_dma(int dev_id, const char *dev_name, |
@@ -799,10 +802,13 @@ void omap_free_dma(int lch) | |||
799 | 802 | ||
800 | if (cpu_class_is_omap2()) { | 803 | if (cpu_class_is_omap2()) { |
801 | u32 val; | 804 | u32 val; |
805 | |||
806 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
802 | /* Disable interrupts */ | 807 | /* Disable interrupts */ |
803 | val = dma_read(IRQENABLE_L0); | 808 | val = dma_read(IRQENABLE_L0); |
804 | val &= ~(1 << lch); | 809 | val &= ~(1 << lch); |
805 | dma_write(val, IRQENABLE_L0); | 810 | dma_write(val, IRQENABLE_L0); |
811 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
806 | 812 | ||
807 | /* Clear the CSR register and IRQ status register */ | 813 | /* Clear the CSR register and IRQ status register */ |
808 | dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); | 814 | dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); |
@@ -829,10 +835,10 @@ EXPORT_SYMBOL(omap_free_dma); | |||
829 | * | 835 | * |
830 | * @param arb_rate | 836 | * @param arb_rate |
831 | * @param max_fifo_depth | 837 | * @param max_fifo_depth |
832 | * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM | 838 | * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM |
833 | * DMA_THREAD_RESERVE_ONET | 839 | * DMA_THREAD_RESERVE_ONET |
834 | * DMA_THREAD_RESERVE_TWOT | 840 | * DMA_THREAD_RESERVE_TWOT |
835 | * DMA_THREAD_RESERVE_THREET | 841 | * DMA_THREAD_RESERVE_THREET |
836 | */ | 842 | */ |
837 | void | 843 | void |
838 | omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) | 844 | omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) |
@@ -844,11 +850,14 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) | |||
844 | return; | 850 | return; |
845 | } | 851 | } |
846 | 852 | ||
853 | if (max_fifo_depth == 0) | ||
854 | max_fifo_depth = 1; | ||
847 | if (arb_rate == 0) | 855 | if (arb_rate == 0) |
848 | arb_rate = 1; | 856 | arb_rate = 1; |
849 | 857 | ||
850 | reg = (arb_rate & 0xff) << 16; | 858 | reg = 0xff & max_fifo_depth; |
851 | reg |= (0xff & max_fifo_depth); | 859 | reg |= (0x3 & tparams) << 12; |
860 | reg |= (arb_rate & 0xff) << 16; | ||
852 | 861 | ||
853 | dma_write(reg, GCR); | 862 | dma_write(reg, GCR); |
854 | } | 863 | } |
@@ -975,6 +984,14 @@ void omap_stop_dma(int lch) | |||
975 | { | 984 | { |
976 | u32 l; | 985 | u32 l; |
977 | 986 | ||
987 | /* Disable all interrupts on the channel */ | ||
988 | if (cpu_class_is_omap1()) | ||
989 | dma_write(0, CICR(lch)); | ||
990 | |||
991 | l = dma_read(CCR(lch)); | ||
992 | l &= ~OMAP_DMA_CCR_EN; | ||
993 | dma_write(l, CCR(lch)); | ||
994 | |||
978 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 995 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
979 | int next_lch, cur_lch = lch; | 996 | int next_lch, cur_lch = lch; |
980 | char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; | 997 | char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; |
@@ -992,18 +1009,8 @@ void omap_stop_dma(int lch) | |||
992 | next_lch = dma_chan[cur_lch].next_lch; | 1009 | next_lch = dma_chan[cur_lch].next_lch; |
993 | cur_lch = next_lch; | 1010 | cur_lch = next_lch; |
994 | } while (next_lch != -1); | 1011 | } while (next_lch != -1); |
995 | |||
996 | return; | ||
997 | } | 1012 | } |
998 | 1013 | ||
999 | /* Disable all interrupts on the channel */ | ||
1000 | if (cpu_class_is_omap1()) | ||
1001 | dma_write(0, CICR(lch)); | ||
1002 | |||
1003 | l = dma_read(CCR(lch)); | ||
1004 | l &= ~OMAP_DMA_CCR_EN; | ||
1005 | dma_write(l, CCR(lch)); | ||
1006 | |||
1007 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; | 1014 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; |
1008 | } | 1015 | } |
1009 | EXPORT_SYMBOL(omap_stop_dma); | 1016 | EXPORT_SYMBOL(omap_stop_dma); |
@@ -1107,6 +1114,14 @@ int omap_dma_running(void) | |||
1107 | { | 1114 | { |
1108 | int lch; | 1115 | int lch; |
1109 | 1116 | ||
1117 | /* | ||
1118 | * On OMAP1510, internal LCD controller will start the transfer | ||
1119 | * when it gets enabled, so assume DMA running if LCD enabled. | ||
1120 | */ | ||
1121 | if (cpu_is_omap1510()) | ||
1122 | if (omap_readw(0xfffec000 + 0x00) & (1 << 0)) | ||
1123 | return 1; | ||
1124 | |||
1110 | /* Check if LCD DMA is running */ | 1125 | /* Check if LCD DMA is running */ |
1111 | if (cpu_is_omap16xx()) | 1126 | if (cpu_is_omap16xx()) |
1112 | if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) | 1127 | if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) |