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