aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dma.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2008-07-03 05:24:31 -0400
committerTony Lindgren <tony@atomide.com>2008-07-03 05:24:31 -0400
commit4d96372e6daae89166fed7883ee092dc8db80b21 (patch)
tree56814f4e3909e1337b4c8014c1989f9345ed1ba9 /arch/arm/plat-omap/dma.c
parent4a79acdc784c315d9c436ba2315d08f8f53b8adf (diff)
ARM: OMAP: DMA: Make channels dynamic for multi-boot
Make DMA channels dynamic for multi-boot Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r--arch/arm/plat-omap/dma.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 39c637b0ffea..02f00a98783f 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -72,7 +72,6 @@ struct omap_dma_lch {
72 long flags; 72 long flags;
73}; 73};
74 74
75#ifndef CONFIG_ARCH_OMAP1
76struct dma_link_info { 75struct dma_link_info {
77 int *linked_dmach_q; 76 int *linked_dmach_q;
78 int no_of_lchs_linked; 77 int no_of_lchs_linked;
@@ -86,7 +85,9 @@ struct dma_link_info {
86 85
87}; 86};
88 87
89static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; 88static struct dma_link_info *dma_linked_lch;
89
90#ifndef CONFIG_ARCH_OMAP1
90 91
91/* Chain handling macros */ 92/* Chain handling macros */
92#define OMAP_DMA_CHAIN_QINIT(chain_id) \ 93#define OMAP_DMA_CHAIN_QINIT(chain_id) \
@@ -119,12 +120,14 @@ static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT];
119 dma_linked_lch[chain_id].q_count++; \ 120 dma_linked_lch[chain_id].q_count++; \
120 } while (0) 121 } while (0)
121#endif 122#endif
123
124static int dma_lch_count;
122static int dma_chan_count; 125static int dma_chan_count;
123 126
124static spinlock_t dma_chan_lock; 127static spinlock_t dma_chan_lock;
125static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; 128static struct omap_dma_lch *dma_chan;
126 129
127static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { 130static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
128 INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, 131 INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
129 INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, 132 INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
130 INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, 133 INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
@@ -727,7 +730,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
727{ 730{
728 u32 w; 731 u32 w;
729 732
730 if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) { 733 if (unlikely((lch < 0 || lch >= dma_lch_count))) {
731 printk(KERN_ERR "Invalid channel id\n"); 734 printk(KERN_ERR "Invalid channel id\n");
732 return -EINVAL; 735 return -EINVAL;
733 } 736 }
@@ -775,7 +778,7 @@ void omap_start_dma(int lch)
775{ 778{
776 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { 779 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
777 int next_lch, cur_lch; 780 int next_lch, cur_lch;
778 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; 781 char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
779 782
780 dma_chan_link_map[lch] = 1; 783 dma_chan_link_map[lch] = 1;
781 /* Set the link register of the first channel */ 784 /* Set the link register of the first channel */
@@ -819,7 +822,7 @@ void omap_stop_dma(int lch)
819{ 822{
820 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { 823 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
821 int next_lch, cur_lch = lch; 824 int next_lch, cur_lch = lch;
822 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; 825 char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
823 826
824 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); 827 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
825 do { 828 do {
@@ -1061,7 +1064,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name,
1061 } 1064 }
1062 1065
1063 if (unlikely((no_of_chans < 1 1066 if (unlikely((no_of_chans < 1
1064 || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) { 1067 || no_of_chans > dma_lch_count))) {
1065 printk(KERN_ERR "Invalid Number of channels requested\n"); 1068 printk(KERN_ERR "Invalid Number of channels requested\n");
1066 return -EINVAL; 1069 return -EINVAL;
1067 } 1070 }
@@ -1138,7 +1141,7 @@ int omap_modify_dma_chain_params(int chain_id,
1138 1141
1139 /* Check for input params */ 1142 /* Check for input params */
1140 if (unlikely((chain_id < 0 1143 if (unlikely((chain_id < 0
1141 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1144 || chain_id >= dma_lch_count))) {
1142 printk(KERN_ERR "Invalid chain id\n"); 1145 printk(KERN_ERR "Invalid chain id\n");
1143 return -EINVAL; 1146 return -EINVAL;
1144 } 1147 }
@@ -1176,7 +1179,7 @@ int omap_free_dma_chain(int chain_id)
1176 u32 i; 1179 u32 i;
1177 1180
1178 /* Check for input params */ 1181 /* Check for input params */
1179 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1182 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1180 printk(KERN_ERR "Invalid chain id\n"); 1183 printk(KERN_ERR "Invalid chain id\n");
1181 return -EINVAL; 1184 return -EINVAL;
1182 } 1185 }
@@ -1216,7 +1219,7 @@ EXPORT_SYMBOL(omap_free_dma_chain);
1216int omap_dma_chain_status(int chain_id) 1219int omap_dma_chain_status(int chain_id)
1217{ 1220{
1218 /* Check for input params */ 1221 /* Check for input params */
1219 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1222 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1220 printk(KERN_ERR "Invalid chain id\n"); 1223 printk(KERN_ERR "Invalid chain id\n");
1221 return -EINVAL; 1224 return -EINVAL;
1222 } 1225 }
@@ -1265,7 +1268,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
1265 1268
1266 /* Check for input params */ 1269 /* Check for input params */
1267 if (unlikely((chain_id < 0 1270 if (unlikely((chain_id < 0
1268 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1271 || chain_id >= dma_lch_count))) {
1269 printk(KERN_ERR "Invalid chain id\n"); 1272 printk(KERN_ERR "Invalid chain id\n");
1270 return -EINVAL; 1273 return -EINVAL;
1271 } 1274 }
@@ -1382,7 +1385,7 @@ int omap_start_dma_chain_transfers(int chain_id)
1382 int *channels; 1385 int *channels;
1383 u32 w, i; 1386 u32 w, i;
1384 1387
1385 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1388 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1386 printk(KERN_ERR "Invalid chain id\n"); 1389 printk(KERN_ERR "Invalid chain id\n");
1387 return -EINVAL; 1390 return -EINVAL;
1388 } 1391 }
@@ -1435,7 +1438,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
1435 u32 sys_cf; 1438 u32 sys_cf;
1436 1439
1437 /* Check for input params */ 1440 /* Check for input params */
1438 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1441 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1439 printk(KERN_ERR "Invalid chain id\n"); 1442 printk(KERN_ERR "Invalid chain id\n");
1440 return -EINVAL; 1443 return -EINVAL;
1441 } 1444 }
@@ -1497,7 +1500,7 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
1497 int *channels; 1500 int *channels;
1498 1501
1499 /* Check for input params */ 1502 /* Check for input params */
1500 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1503 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1501 printk(KERN_ERR "Invalid chain id\n"); 1504 printk(KERN_ERR "Invalid chain id\n");
1502 return -EINVAL; 1505 return -EINVAL;
1503 } 1506 }
@@ -1537,7 +1540,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
1537 int *channels; 1540 int *channels;
1538 1541
1539 /* Check for input params */ 1542 /* Check for input params */
1540 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1543 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1541 printk(KERN_ERR "Invalid chain id\n"); 1544 printk(KERN_ERR "Invalid chain id\n");
1542 return -EINVAL; 1545 return -EINVAL;
1543 } 1546 }
@@ -1571,7 +1574,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
1571 int *channels; 1574 int *channels;
1572 1575
1573 /* Check for input params */ 1576 /* Check for input params */
1574 if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1577 if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
1575 printk(KERN_ERR "Invalid chain id\n"); 1578 printk(KERN_ERR "Invalid chain id\n");
1576 return -EINVAL; 1579 return -EINVAL;
1577 } 1580 }
@@ -1724,7 +1727,7 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
1724 printk(KERN_WARNING "Spurious DMA IRQ\n"); 1727 printk(KERN_WARNING "Spurious DMA IRQ\n");
1725 return IRQ_HANDLED; 1728 return IRQ_HANDLED;
1726 } 1729 }
1727 for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) { 1730 for (i = 0; i < dma_lch_count && val != 0; i++) {
1728 if (val & 1) 1731 if (val & 1)
1729 omap2_dma_handle_ch(i); 1732 omap2_dma_handle_ch(i);
1730 val >>= 1; 1733 val >>= 1;
@@ -2106,6 +2109,25 @@ static int __init omap_init_dma(void)
2106{ 2109{
2107 int ch, r; 2110 int ch, r;
2108 2111
2112 if (cpu_class_is_omap1())
2113 dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
2114 else
2115 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2116
2117 dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
2118 GFP_KERNEL);
2119 if (!dma_chan)
2120 return -ENOMEM;
2121
2122 if (cpu_class_is_omap2()) {
2123 dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
2124 dma_lch_count, GFP_KERNEL);
2125 if (!dma_linked_lch) {
2126 kfree(dma_chan);
2127 return -ENOMEM;
2128 }
2129 }
2130
2109 if (cpu_is_omap15xx()) { 2131 if (cpu_is_omap15xx()) {
2110 printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); 2132 printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
2111 dma_chan_count = 9; 2133 dma_chan_count = 9;
@@ -2142,16 +2164,14 @@ static int __init omap_init_dma(void)
2142 u8 revision = omap_readb(OMAP_DMA4_REVISION); 2164 u8 revision = omap_readb(OMAP_DMA4_REVISION);
2143 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 2165 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
2144 revision >> 4, revision & 0xf); 2166 revision >> 4, revision & 0xf);
2145 dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; 2167 dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2146 } else { 2168 } else {
2147 dma_chan_count = 0; 2169 dma_chan_count = 0;
2148 return 0; 2170 return 0;
2149 } 2171 }
2150 2172
2151 memset(&lcd_dma, 0, sizeof(lcd_dma));
2152 spin_lock_init(&lcd_dma.lock); 2173 spin_lock_init(&lcd_dma.lock);
2153 spin_lock_init(&dma_chan_lock); 2174 spin_lock_init(&dma_chan_lock);
2154 memset(&dma_chan, 0, sizeof(dma_chan));
2155 2175
2156 for (ch = 0; ch < dma_chan_count; ch++) { 2176 for (ch = 0; ch < dma_chan_count; ch++) {
2157 omap_clear_dma(ch); 2177 omap_clear_dma(ch);