upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / arch / arm / mach-omap / dma.c
1 /*
2  * linux/arch/arm/omap/dma.c
3  *
4  * Copyright (C) 2003 Nokia Corporation
5  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
6  * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
7  * Graphics DMA and LCD DMA graphics tranformations
8  * by Imre Deak <imre.deak@nokia.com>
9  *
10  * Support functions for the OMAP internal DMA channels.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/sched.h>
21 #include <linux/spinlock.h>
22 #include <linux/errno.h>
23 #include <linux/interrupt.h>
24
25 #include <asm/system.h>
26 #include <asm/irq.h>
27 #include <asm/hardware.h>
28 #include <asm/dma.h>
29 #include <asm/io.h>
30
31 #include <asm/arch/tc.h>
32
33 #define OMAP_DMA_ACTIVE         0x01
34
35 #define OMAP_DMA_CCR_EN         (1 << 7)
36
37 #define OMAP_FUNC_MUX_ARM_BASE  (0xfffe1000 + 0xec)
38
39 static int enable_1510_mode = 0;
40
41 struct omap_dma_lch {
42         int next_lch;
43         int dev_id;
44         u16 saved_csr;
45         u16 enabled_irqs;
46         const char *dev_name;
47         void (* callback)(int lch, u16 ch_status, void *data);
48         void *data;
49         long flags;
50 };
51
52 static int dma_chan_count;
53
54 static spinlock_t dma_chan_lock;
55 static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
56
57 const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
58         INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
59         INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
60         INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
61         INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
62         INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
63 };
64
65 static inline int get_gdma_dev(int req)
66 {
67         u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
68         int shift = ((req - 1) % 5) * 6;
69
70         return ((omap_readl(reg) >> shift) & 0x3f) + 1;
71 }
72
73 static inline void set_gdma_dev(int req, int dev)
74 {
75         u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
76         int shift = ((req - 1) % 5) * 6;
77         u32 l;
78
79         l = omap_readl(reg);
80         l &= ~(0x3f << shift);
81         l |= (dev - 1) << shift;
82         omap_writel(l, reg);
83 }
84
85 static void clear_lch_regs(int lch)
86 {
87         int i;
88         u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
89
90         for (i = 0; i < 0x2c; i += 2)
91                 omap_writew(0, lch_base + i);
92 }
93
94 void omap_set_dma_priority(int dst_port, int priority)
95 {
96         unsigned long reg;
97         u32 l;
98
99         switch (dst_port) {
100         case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
101                 reg = OMAP_TC_OCPT1_PRIOR;
102                 break;
103         case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
104                 reg = OMAP_TC_OCPT2_PRIOR;
105                 break;
106         case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
107                 reg = OMAP_TC_EMIFF_PRIOR;
108                 break;
109         case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
110                 reg = OMAP_TC_EMIFS_PRIOR;
111                 break;
112         default:
113                 BUG();
114                 return;
115         }
116         l = omap_readl(reg);
117         l &= ~(0xf << 8);
118         l |= (priority & 0xf) << 8;
119         omap_writel(l, reg);
120 }
121
122 void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
123                                   int frame_count, int sync_mode)
124 {
125         u16 w;
126
127         w = omap_readw(OMAP_DMA_CSDP(lch));
128         w &= ~0x03;
129         w |= data_type;
130         omap_writew(w, OMAP_DMA_CSDP(lch));
131
132         w = omap_readw(OMAP_DMA_CCR(lch));
133         w &= ~(1 << 5);
134         if (sync_mode == OMAP_DMA_SYNC_FRAME)
135                 w |= 1 << 5;
136         omap_writew(w, OMAP_DMA_CCR(lch));
137
138         w = omap_readw(OMAP_DMA_CCR2(lch));
139         w &= ~(1 << 2);
140         if (sync_mode == OMAP_DMA_SYNC_BLOCK)
141                 w |= 1 << 2;
142         omap_writew(w, OMAP_DMA_CCR2(lch));
143
144         omap_writew(elem_count, OMAP_DMA_CEN(lch));
145         omap_writew(frame_count, OMAP_DMA_CFN(lch));
146
147 }
148 void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
149 {
150         u16 w;
151
152         BUG_ON(omap_dma_in_1510_mode());
153
154         w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
155         switch (mode) {
156         case OMAP_DMA_CONSTANT_FILL:
157                 w |= 0x01;
158                 break;
159         case OMAP_DMA_TRANSPARENT_COPY:
160                 w |= 0x02;
161                 break;
162         case OMAP_DMA_COLOR_DIS:
163                 break;
164         default:
165                 BUG();
166         }
167         omap_writew(w, OMAP_DMA_CCR2(lch));
168
169         w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
170         /* Default is channel type 2D */
171         if (mode) {
172                 omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
173                 omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
174                 w |= 1;         /* Channel type G */
175         }
176         omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
177 }
178
179
180 void omap_set_dma_src_params(int lch, int src_port, int src_amode,
181                              unsigned long src_start)
182 {
183         u16 w;
184
185         w = omap_readw(OMAP_DMA_CSDP(lch));
186         w &= ~(0x1f << 2);
187         w |= src_port << 2;
188         omap_writew(w, OMAP_DMA_CSDP(lch));
189
190         w = omap_readw(OMAP_DMA_CCR(lch));
191         w &= ~(0x03 << 12);
192         w |= src_amode << 12;
193         omap_writew(w, OMAP_DMA_CCR(lch));
194
195         omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
196         omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
197 }
198
199 void omap_set_dma_src_index(int lch, int eidx, int fidx)
200 {
201         omap_writew(eidx, OMAP_DMA_CSEI(lch));
202         omap_writew(fidx, OMAP_DMA_CSFI(lch));
203 }
204
205 void omap_set_dma_src_data_pack(int lch, int enable)
206 {
207         u16 w;
208
209         w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
210         w |= enable ? (1 << 6) : 0;
211         omap_writew(w, OMAP_DMA_CSDP(lch));
212 }
213
214 void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
215 {
216         u16 w;
217
218         w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
219         switch (burst_mode) {
220         case OMAP_DMA_DATA_BURST_DIS:
221                 break;
222         case OMAP_DMA_DATA_BURST_4:
223                 w |= (0x01 << 7);
224                 break;
225         case OMAP_DMA_DATA_BURST_8:
226                 /* not supported by current hardware
227                  * w |= (0x03 << 7);
228                  * fall through
229                  */
230         default:
231                 BUG();
232         }
233         omap_writew(w, OMAP_DMA_CSDP(lch));
234 }
235
236 void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
237                               unsigned long dest_start)
238 {
239         u16 w;
240
241         w = omap_readw(OMAP_DMA_CSDP(lch));
242         w &= ~(0x1f << 9);
243         w |= dest_port << 9;
244         omap_writew(w, OMAP_DMA_CSDP(lch));
245
246         w = omap_readw(OMAP_DMA_CCR(lch));
247         w &= ~(0x03 << 14);
248         w |= dest_amode << 14;
249         omap_writew(w, OMAP_DMA_CCR(lch));
250
251         omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
252         omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
253 }
254
255 void omap_set_dma_dest_index(int lch, int eidx, int fidx)
256 {
257         omap_writew(eidx, OMAP_DMA_CDEI(lch));
258         omap_writew(fidx, OMAP_DMA_CDFI(lch));
259 }
260
261 void omap_set_dma_dest_data_pack(int lch, int enable)
262 {
263         u16 w;
264
265         w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
266         w |= enable ? (1 << 13) : 0;
267         omap_writew(w, OMAP_DMA_CSDP(lch));
268 }
269
270 void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
271 {
272         u16 w;
273
274         w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
275         switch (burst_mode) {
276         case OMAP_DMA_DATA_BURST_DIS:
277                 break;
278         case OMAP_DMA_DATA_BURST_4:
279                 w |= (0x01 << 14);
280                 break;
281         case OMAP_DMA_DATA_BURST_8:
282                 w |= (0x03 << 14);
283                 break;
284         default:
285                 printk(KERN_ERR "Invalid DMA burst mode\n");
286                 BUG();
287                 return;
288         }
289         omap_writew(w, OMAP_DMA_CSDP(lch));
290 }
291
292 static inline void init_intr(int lch)
293 {
294         u16 w;
295
296         /* Read CSR to make sure it's cleared. */
297         w = omap_readw(OMAP_DMA_CSR(lch));
298         /* Enable some nice interrupts. */
299         omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
300         dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
301 }
302
303 static inline void enable_lnk(int lch)
304 {
305         u16 w;
306
307         /* Clear the STOP_LNK bits */
308         w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
309         w &= ~(1 << 14);
310         omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
311
312         /* And set the ENABLE_LNK bits */
313         if (dma_chan[lch].next_lch != -1)
314                 omap_writew(dma_chan[lch].next_lch | (1 << 15),
315                             OMAP_DMA_CLNK_CTRL(lch));
316 }
317
318 static inline void disable_lnk(int lch)
319 {
320         u16 w;
321
322         /* Disable interrupts */
323         omap_writew(0, OMAP_DMA_CICR(lch));
324
325         /* Set the STOP_LNK bit */
326         w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
327         w |= (1 << 14);
328         w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
329
330         dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
331 }
332
333 void omap_start_dma(int lch)
334 {
335         u16 w;
336
337         if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
338                 int next_lch, cur_lch;
339                 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
340
341                 dma_chan_link_map[lch] = 1;
342                 /* Set the link register of the first channel */
343                 enable_lnk(lch);
344
345                 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
346                 cur_lch = dma_chan[lch].next_lch;
347                 do {
348                         next_lch = dma_chan[cur_lch].next_lch;
349
350                         /* The loop case: we've been here already */
351                         if (dma_chan_link_map[cur_lch])
352                                 break;
353                         /* Mark the current channel */
354                         dma_chan_link_map[cur_lch] = 1;
355
356                         enable_lnk(cur_lch);
357                         init_intr(cur_lch);
358
359                         cur_lch = next_lch;
360                 } while (next_lch != -1);
361         }
362
363         init_intr(lch);
364
365         w = omap_readw(OMAP_DMA_CCR(lch));
366         w |= OMAP_DMA_CCR_EN;
367         omap_writew(w, OMAP_DMA_CCR(lch));
368         dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
369 }
370
371 void omap_stop_dma(int lch)
372 {
373         u16 w;
374
375         if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
376                 int next_lch, cur_lch = lch;
377                 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
378
379                 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
380                 do {
381                         /* The loop case: we've been here already */
382                         if (dma_chan_link_map[cur_lch])
383                                 break;
384                         /* Mark the current channel */
385                         dma_chan_link_map[cur_lch] = 1;
386
387                         disable_lnk(cur_lch);
388
389                         next_lch = dma_chan[cur_lch].next_lch;
390                         cur_lch = next_lch;
391                 } while (next_lch != -1);
392
393                 return;
394         }
395         /* Disable all interrupts on the channel */
396         omap_writew(0, OMAP_DMA_CICR(lch));
397
398         w = omap_readw(OMAP_DMA_CCR(lch));
399         w &= ~OMAP_DMA_CCR_EN;
400         omap_writew(w, OMAP_DMA_CCR(lch));
401         dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
402 }
403
404 void omap_enable_dma_irq(int lch, u16 bits)
405 {
406         dma_chan[lch].enabled_irqs |= bits;
407 }
408
409 void omap_disable_dma_irq(int lch, u16 bits)
410 {
411         dma_chan[lch].enabled_irqs &= ~bits;
412 }
413
414 static int dma_handle_ch(int ch)
415 {
416         u16 csr;
417
418         if (enable_1510_mode && ch >= 6) {
419                 csr = dma_chan[ch].saved_csr;
420                 dma_chan[ch].saved_csr = 0;
421         } else
422                 csr = omap_readw(OMAP_DMA_CSR(ch));
423         if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
424                 dma_chan[ch + 6].saved_csr = csr >> 7;
425                 csr &= 0x7f;
426         }
427         if (!csr)
428                 return 0;
429         if (unlikely(dma_chan[ch].dev_id == -1)) {
430                 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
431                        ch, csr);
432                 return 0;
433         }
434         if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
435                 printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
436         if (unlikely(csr & OMAP_DMA_DROP_IRQ))
437                 printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
438                        dma_chan[ch].dev_id);
439         if (likely(csr & OMAP_DMA_BLOCK_IRQ))
440                 dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
441         if (likely(dma_chan[ch].callback != NULL))
442                 dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
443         return 1;
444 }
445
446 static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
447 {
448         int ch = ((int) dev_id) - 1;
449         int handled = 0;
450
451         for (;;) {
452                 int handled_now = 0;
453
454                 handled_now += dma_handle_ch(ch);
455                 if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
456                         handled_now += dma_handle_ch(ch + 6);
457                 if (!handled_now)
458                         break;
459                 handled += handled_now;
460         }
461
462         return handled ? IRQ_HANDLED : IRQ_NONE;
463 }
464
465 int omap_request_dma(int dev_id, const char *dev_name,
466                      void (* callback)(int lch, u16 ch_status, void *data),
467                      void *data, int *dma_ch_out)
468 {
469         int ch, free_ch = -1;
470         unsigned long flags;
471         struct omap_dma_lch *chan;
472
473         spin_lock_irqsave(&dma_chan_lock, flags);
474         for (ch = 0; ch < dma_chan_count; ch++) {
475                 if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
476                         free_ch = ch;
477                         if (dev_id == 0)
478                                 break;
479                 }
480                 if (dev_id != 0 && dma_chan[ch].dev_id == dev_id) {
481                         spin_unlock_irqrestore(&dma_chan_lock, flags);
482                         return -EAGAIN;
483                 }
484         }
485         if (free_ch == -1) {
486                 spin_unlock_irqrestore(&dma_chan_lock, flags);
487                 return -EBUSY;
488         }
489         chan = dma_chan + free_ch;
490         chan->dev_id = dev_id;
491         clear_lch_regs(free_ch);
492         spin_unlock_irqrestore(&dma_chan_lock, flags);
493
494         chan->dev_id = dev_id;
495         chan->dev_name = dev_name;
496         chan->callback = callback;
497         chan->data = data;
498         chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
499
500         if (cpu_is_omap16xx() || cpu_is_omap730()) {
501                 /* If the sync device is set, configure it dynamically. */
502                 if (dev_id != 0) {
503                         set_gdma_dev(free_ch + 1, dev_id);
504                         dev_id = free_ch + 1;
505                 }
506                 /* Disable the 1510 compatibility mode and set the sync device
507                  * id. */
508                 omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
509         } else {
510                 omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
511         }
512         *dma_ch_out = free_ch;
513
514         return 0;
515 }
516
517 void omap_free_dma(int ch)
518 {
519         unsigned long flags;
520
521         spin_lock_irqsave(&dma_chan_lock, flags);
522         if (dma_chan[ch].dev_id == -1) {
523                 printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch);
524                 spin_unlock_irqrestore(&dma_chan_lock, flags);
525                 return;
526         }
527         dma_chan[ch].dev_id = -1;
528         spin_unlock_irqrestore(&dma_chan_lock, flags);
529
530         /* Disable all DMA interrupts for the channel. */
531         omap_writew(0, OMAP_DMA_CICR(ch));
532         /* Make sure the DMA transfer is stopped. */
533         omap_writew(0, OMAP_DMA_CCR(ch));
534 }
535
536 int omap_dma_in_1510_mode(void)
537 {
538         return enable_1510_mode;
539 }
540
541 /*
542  * lch_queue DMA will start right after lch_head one is finished.
543  * For this DMA link to start, you still need to start (see omap_start_dma)
544  * the first one. That will fire up the entire queue.
545  */
546 void omap_dma_link_lch (int lch_head, int lch_queue)
547 {
548         if (omap_dma_in_1510_mode()) {
549                 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
550                 BUG();
551                 return;
552         }
553
554         if ((dma_chan[lch_head].dev_id == -1) ||
555             (dma_chan[lch_queue].dev_id == -1)) {
556                 printk(KERN_ERR "omap_dma: trying to link non requested channels\n");
557                 dump_stack();
558         }
559
560         dma_chan[lch_head].next_lch = lch_queue;
561 }
562
563 /*
564  * Once the DMA queue is stopped, we can destroy it.
565  */
566 void omap_dma_unlink_lch (int lch_head, int lch_queue)
567 {
568         if (omap_dma_in_1510_mode()) {
569                 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
570                 BUG();
571                 return;
572         }
573
574         if (dma_chan[lch_head].next_lch != lch_queue ||
575             dma_chan[lch_head].next_lch == -1) {
576                 printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n");
577                 dump_stack();
578         }
579
580
581         if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
582             (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
583                 printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n");
584                 dump_stack();
585         }
586
587         dma_chan[lch_head].next_lch = -1;
588 }
589
590
591 static struct lcd_dma_info {
592         spinlock_t lock;
593         int reserved;
594         void (* callback)(u16 status, void *data);
595         void *cb_data;
596
597         int active;
598         unsigned long addr, size;
599         int rotate, data_type, xres, yres;
600         int vxres;
601         int mirror;
602         int xscale, yscale;
603         int ext_ctrl;
604         int src_port;
605         int single_transfer;
606 } lcd_dma;
607
608 void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
609                          int data_type)
610 {
611         lcd_dma.addr = addr;
612         lcd_dma.data_type = data_type;
613         lcd_dma.xres = fb_xres;
614         lcd_dma.yres = fb_yres;
615 }
616
617 void omap_set_lcd_dma_src_port(int port)
618 {
619         lcd_dma.src_port = port;
620 }
621
622 void omap_set_lcd_dma_ext_controller(int external)
623 {
624         lcd_dma.ext_ctrl = external;
625 }
626
627 void omap_set_lcd_dma_single_transfer(int single)
628 {
629         lcd_dma.single_transfer = single;
630 }
631
632
633 void omap_set_lcd_dma_b1_rotation(int rotate)
634 {
635         if (omap_dma_in_1510_mode()) {
636                 printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
637                 BUG();
638                 return;
639         }
640         lcd_dma.rotate = rotate;
641 }
642
643 void omap_set_lcd_dma_b1_mirror(int mirror)
644 {
645         if (omap_dma_in_1510_mode()) {
646                 printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
647                 BUG();
648         }
649         lcd_dma.mirror = mirror;
650 }
651
652 void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
653 {
654         if (omap_dma_in_1510_mode()) {
655                 printk(KERN_ERR "DMA virtual resulotion is not supported "
656                                 "in 1510 mode\n");
657                 BUG();
658         }
659         lcd_dma.vxres = vxres;
660 }
661
662 void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
663 {
664         if (omap_dma_in_1510_mode()) {
665                 printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
666                 BUG();
667         }
668         lcd_dma.xscale = xscale;
669         lcd_dma.yscale = yscale;
670 }
671
672 static void set_b1_regs(void)
673 {
674         unsigned long top, bottom;
675         int es;
676         u16 w;
677         unsigned long en, fn;
678         long ei, fi;
679         unsigned long vxres;
680         unsigned int xscale, yscale;
681
682         switch (lcd_dma.data_type) {
683         case OMAP_DMA_DATA_TYPE_S8:
684                 es = 1;
685                 break;
686         case OMAP_DMA_DATA_TYPE_S16:
687                 es = 2;
688                 break;
689         case OMAP_DMA_DATA_TYPE_S32:
690                 es = 4;
691                 break;
692         default:
693                 BUG();
694                 return;
695         }
696
697         vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
698         xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
699         yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
700         BUG_ON(vxres < lcd_dma.xres);
701 #define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
702 #define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
703         switch (lcd_dma.rotate) {
704         case 0:
705                 if (!lcd_dma.mirror) {
706                         top = PIXADDR(0, 0);
707                         bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
708                         /* 1510 DMA requires the bottom address to be 2 more
709                          * than the actual last memory access location. */
710                         if (omap_dma_in_1510_mode() &&
711                             lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
712                                 bottom += 2;
713                         ei = PIXSTEP(0, 0, 1, 0);
714                         fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
715                 } else {
716                         top = PIXADDR(lcd_dma.xres - 1, 0);
717                         bottom = PIXADDR(0, lcd_dma.yres - 1);
718                         ei = PIXSTEP(1, 0, 0, 0);
719                         fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
720                 }
721                 en = lcd_dma.xres;
722                 fn = lcd_dma.yres;
723                 break;
724         case 90:
725                 if (!lcd_dma.mirror) {
726                         top = PIXADDR(0, lcd_dma.yres - 1);
727                         bottom = PIXADDR(lcd_dma.xres - 1, 0);
728                         ei = PIXSTEP(0, 1, 0, 0);
729                         fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
730                 } else {
731                         top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
732                         bottom = PIXADDR(0, 0);
733                         ei = PIXSTEP(0, 1, 0, 0);
734                         fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
735                 }
736                 en = lcd_dma.yres;
737                 fn = lcd_dma.xres;
738                 break;
739         case 180:
740                 if (!lcd_dma.mirror) {
741                         top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
742                         bottom = PIXADDR(0, 0);
743                         ei = PIXSTEP(1, 0, 0, 0);
744                         fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
745                 } else {
746                         top = PIXADDR(0, lcd_dma.yres - 1);
747                         bottom = PIXADDR(lcd_dma.xres - 1, 0);
748                         ei = PIXSTEP(0, 0, 1, 0);
749                         fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
750                 }
751                 en = lcd_dma.xres;
752                 fn = lcd_dma.yres;
753                 break;
754         case 270:
755                 if (!lcd_dma.mirror) {
756                         top = PIXADDR(lcd_dma.xres - 1, 0);
757                         bottom = PIXADDR(0, lcd_dma.yres - 1);
758                         ei = PIXSTEP(0, 0, 0, 1);
759                         fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
760                 } else {
761                         top = PIXADDR(0, 0);
762                         bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
763                         ei = PIXSTEP(0, 0, 0, 1);
764                         fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
765                 }
766                 en = lcd_dma.yres;
767                 fn = lcd_dma.xres;
768                 break;
769         default:
770                 BUG();
771                 return; /* Supress warning about uninitialized vars */
772         }
773
774         if (omap_dma_in_1510_mode()) {
775                 omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
776                 omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
777                 omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
778                 omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
779
780                 return;
781         }
782
783         /* 1610 regs */
784         omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
785         omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
786         omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
787         omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
788
789         omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
790         omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
791
792         w = omap_readw(OMAP1610_DMA_LCD_CSDP);
793         w &= ~0x03;
794         w |= lcd_dma.data_type;
795         omap_writew(w, OMAP1610_DMA_LCD_CSDP);
796
797         w = omap_readw(OMAP1610_DMA_LCD_CTRL);
798         /* Always set the source port as SDRAM for now*/
799         w &= ~(0x03 << 6);
800         if (lcd_dma.ext_ctrl)
801                 w |= 1 << 8;
802         else
803                 w &= ~(1 << 8);
804         if (lcd_dma.callback != NULL)
805                 w |= 1 << 1;            /* Block interrupt enable */
806         else
807                 w &= ~(1 << 1);
808         omap_writew(w, OMAP1610_DMA_LCD_CTRL);
809
810         if (!(lcd_dma.rotate || lcd_dma.mirror ||
811               lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
812                 return;
813
814         w = omap_readw(OMAP1610_DMA_LCD_CCR);
815         /* Set the double-indexed addressing mode */
816         w |= (0x03 << 12);
817         omap_writew(w, OMAP1610_DMA_LCD_CCR);
818
819         omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
820         omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
821         omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
822 }
823
824 static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
825 {
826         u16 w;
827
828         w = omap_readw(OMAP1610_DMA_LCD_CTRL);
829         if (unlikely(!(w & (1 << 3)))) {
830                 printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
831                 return IRQ_NONE;
832         }
833         /* Ack the IRQ */
834         w |= (1 << 3);
835         omap_writew(w, OMAP1610_DMA_LCD_CTRL);
836         lcd_dma.active = 0;
837         if (lcd_dma.callback != NULL)
838                 lcd_dma.callback(w, lcd_dma.cb_data);
839
840         return IRQ_HANDLED;
841 }
842
843 int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
844                          void *data)
845 {
846         spin_lock_irq(&lcd_dma.lock);
847         if (lcd_dma.reserved) {
848                 spin_unlock_irq(&lcd_dma.lock);
849                 printk(KERN_ERR "LCD DMA channel already reserved\n");
850                 BUG();
851                 return -EBUSY;
852         }
853         lcd_dma.reserved = 1;
854         spin_unlock_irq(&lcd_dma.lock);
855         lcd_dma.callback = callback;
856         lcd_dma.cb_data = data;
857         lcd_dma.active = 0;
858         lcd_dma.single_transfer = 0;
859         lcd_dma.rotate = 0;
860         lcd_dma.vxres = 0;
861         lcd_dma.mirror = 0;
862         lcd_dma.xscale = 0;
863         lcd_dma.yscale = 0;
864         lcd_dma.ext_ctrl = 0;
865         lcd_dma.src_port = 0;
866
867         return 0;
868 }
869
870 void omap_free_lcd_dma(void)
871 {
872         spin_lock(&lcd_dma.lock);
873         if (!lcd_dma.reserved) {
874                 spin_unlock(&lcd_dma.lock);
875                 printk(KERN_ERR "LCD DMA is not reserved\n");
876                 BUG();
877                 return;
878         }
879         if (!enable_1510_mode)
880                 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
881         lcd_dma.reserved = 0;
882         spin_unlock(&lcd_dma.lock);
883 }
884
885 void omap_enable_lcd_dma(void)
886 {
887         u16 w;
888
889         /* Set the Enable bit only if an external controller is
890          * connected. Otherwise the OMAP internal controller will
891          * start the transfer when it gets enabled.
892          */
893         if (enable_1510_mode || !lcd_dma.ext_ctrl)
894                 return;
895         w = omap_readw(OMAP1610_DMA_LCD_CCR);
896         w |= 1 << 7;
897         omap_writew(w, OMAP1610_DMA_LCD_CCR);
898         lcd_dma.active = 1;
899 }
900
901 void omap_setup_lcd_dma(void)
902 {
903         BUG_ON(lcd_dma.active);
904         if (!enable_1510_mode) {
905                 /* Set some reasonable defaults */
906                 omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
907                 omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
908                 omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
909         }
910         set_b1_regs();
911         if (!enable_1510_mode) {
912                 u16 w;
913
914                 w = omap_readw(OMAP1610_DMA_LCD_CCR);
915                 /* If DMA was already active set the end_prog bit to have
916                  * the programmed register set loaded into the active
917                  * register set.
918                  */
919                 w |= 1 << 11;           /* End_prog */
920                 if (!lcd_dma.single_transfer)
921                         w |= (3 << 8);  /* Auto_init, repeat */
922                 omap_writew(w, OMAP1610_DMA_LCD_CCR);
923         }
924 }
925
926 void omap_stop_lcd_dma(void)
927 {
928         lcd_dma.active = 0;
929         if (!enable_1510_mode && lcd_dma.ext_ctrl)
930                 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7),
931                             OMAP1610_DMA_LCD_CCR);
932 }
933
934 static int __init omap_init_dma(void)
935 {
936         int ch, r;
937
938         if (cpu_is_omap1510()) {
939                 printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
940                 dma_chan_count = 9;
941                 enable_1510_mode = 1;
942         } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
943                 printk(KERN_INFO "OMAP DMA hardware version %d\n",
944                        omap_readw(OMAP_DMA_HW_ID));
945                 printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
946                        (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
947                        (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
948                        omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
949                        omap_readw(OMAP_DMA_CAPS_4));
950                 if (!enable_1510_mode) {
951                         u16 w;
952
953                         /* Disable OMAP 3.0/3.1 compatibility mode. */
954                         w = omap_readw(OMAP_DMA_GSCR);
955                         w |= 1 << 3;
956                         omap_writew(w, OMAP_DMA_GSCR);
957                         dma_chan_count = 16;
958                 } else
959                         dma_chan_count = 9;
960         } else {
961                 dma_chan_count = 0;
962                 return 0;
963         }
964
965         memset(&lcd_dma, 0, sizeof(lcd_dma));
966         spin_lock_init(&lcd_dma.lock);
967         spin_lock_init(&dma_chan_lock);
968         memset(&dma_chan, 0, sizeof(dma_chan));
969
970         for (ch = 0; ch < dma_chan_count; ch++) {
971                 dma_chan[ch].dev_id = -1;
972                 dma_chan[ch].next_lch = -1;
973
974                 if (ch >= 6 && enable_1510_mode)
975                         continue;
976
977                 /* request_irq() doesn't like dev_id (ie. ch) being zero,
978                  * so we have to kludge around this. */
979                 r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
980                                 (void *) (ch + 1));
981                 if (r != 0) {
982                         int i;
983
984                         printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
985                                dma_irq[ch], r);
986                         for (i = 0; i < ch; i++)
987                                 free_irq(dma_irq[i], (void *) (i + 1));
988                         return r;
989                 }
990         }
991         r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
992         if (r != 0) {
993                 int i;
994
995                 printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
996                 for (i = 0; i < dma_chan_count; i++)
997                         free_irq(dma_irq[i], (void *) (i + 1));
998                 return r;
999         }
1000         return 0;
1001 }
1002 arch_initcall(omap_init_dma);
1003
1004
1005 EXPORT_SYMBOL(omap_set_dma_priority);
1006 EXPORT_SYMBOL(omap_request_dma);
1007 EXPORT_SYMBOL(omap_free_dma);
1008 EXPORT_SYMBOL(omap_start_dma);
1009 EXPORT_SYMBOL(omap_stop_dma);
1010 EXPORT_SYMBOL(omap_enable_dma_irq);
1011 EXPORT_SYMBOL(omap_disable_dma_irq);
1012
1013 EXPORT_SYMBOL(omap_set_dma_transfer_params);
1014 EXPORT_SYMBOL(omap_set_dma_color_mode);
1015
1016 EXPORT_SYMBOL(omap_set_dma_src_params);
1017 EXPORT_SYMBOL(omap_set_dma_src_index);
1018 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
1019 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
1020
1021 EXPORT_SYMBOL(omap_set_dma_dest_params);
1022 EXPORT_SYMBOL(omap_set_dma_dest_index);
1023 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
1024 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
1025
1026 EXPORT_SYMBOL(omap_dma_link_lch);
1027 EXPORT_SYMBOL(omap_dma_unlink_lch);
1028
1029 EXPORT_SYMBOL(omap_request_lcd_dma);
1030 EXPORT_SYMBOL(omap_free_lcd_dma);
1031 EXPORT_SYMBOL(omap_enable_lcd_dma);
1032 EXPORT_SYMBOL(omap_setup_lcd_dma);
1033 EXPORT_SYMBOL(omap_stop_lcd_dma);
1034 EXPORT_SYMBOL(omap_set_lcd_dma_b1);
1035 EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
1036 EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
1037 EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
1038 EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
1039 EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
1040 EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
1041