b62bdf18dca4e156d1b00f3b4ea3c887281893a1
[linux-flexiantxendom0-3.2.10.git] / arch / arm / mach-s3c64xx / dma.c
1 /* linux/arch/arm/plat-s3c64xx/dma.c
2  *
3  * Copyright 2009 Openmoko, Inc.
4  * Copyright 2009 Simtec Electronics
5  *      Ben Dooks <ben@simtec.co.uk>
6  *      http://armlinux.simtec.co.uk/
7  *
8  * S3C64XX DMA core
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/interrupt.h>
18 #include <linux/dmapool.h>
19 #include <linux/sysdev.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
22 #include <linux/clk.h>
23 #include <linux/err.h>
24 #include <linux/io.h>
25
26 #include <mach/dma.h>
27 #include <mach/map.h>
28 #include <mach/irqs.h>
29
30 #include <mach/regs-sys.h>
31
32 #include <asm/hardware/pl080.h>
33
34 /* dma channel state information */
35
36 struct s3c64xx_dmac {
37         struct sys_device        sysdev;
38         struct clk              *clk;
39         void __iomem            *regs;
40         struct s3c2410_dma_chan *channels;
41         enum dma_ch              chanbase;
42 };
43
44 /* pool to provide LLI buffers */
45 static struct dma_pool *dma_pool;
46
47 /* Debug configuration and code */
48
49 static unsigned char debug_show_buffs = 0;
50
51 static void dbg_showchan(struct s3c2410_dma_chan *chan)
52 {
53         pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
54                  chan->number,
55                  readl(chan->regs + PL080_CH_SRC_ADDR),
56                  readl(chan->regs + PL080_CH_DST_ADDR),
57                  readl(chan->regs + PL080_CH_LLI),
58                  readl(chan->regs + PL080_CH_CONTROL),
59                  readl(chan->regs + PL080S_CH_CONTROL2),
60                  readl(chan->regs + PL080S_CH_CONFIG));
61 }
62
63 static void show_lli(struct pl080s_lli *lli)
64 {
65         pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
66                  lli, lli->src_addr, lli->dst_addr, lli->next_lli,
67                  lli->control0, lli->control1);
68 }
69
70 static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
71 {
72         struct s3c64xx_dma_buff *ptr;
73         struct s3c64xx_dma_buff *end;
74
75         pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
76                  chan->number, chan->next, chan->curr, chan->end);
77
78         ptr = chan->next;
79         end = chan->end;
80
81         if (debug_show_buffs) {
82                 for (; ptr != NULL; ptr = ptr->next) {
83                         pr_debug("DMA%d: %08x ",
84                                  chan->number, ptr->lli_dma);
85                         show_lli(ptr->lli);
86                 }
87         }
88 }
89
90 /* End of Debug */
91
92 static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
93 {
94         struct s3c2410_dma_chan *chan;
95         unsigned int start, offs;
96
97         start = 0;
98
99         if (channel >= DMACH_PCM1_TX)
100                 start = 8;
101
102         for (offs = 0; offs < 8; offs++) {
103                 chan = &s3c2410_chans[start + offs];
104                 if (!chan->in_use)
105                         goto found;
106         }
107
108         return NULL;
109
110 found:
111         s3c_dma_chan_map[channel] = chan;
112         return chan;
113 }
114
115 int s3c2410_dma_config(unsigned int channel, int xferunit)
116 {
117         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
118
119         if (chan == NULL)
120                 return -EINVAL;
121
122         switch (xferunit) {
123         case 1:
124                 chan->hw_width = 0;
125                 break;
126         case 2:
127                 chan->hw_width = 1;
128                 break;
129         case 4:
130                 chan->hw_width = 2;
131                 break;
132         default:
133                 printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
134                 return -EINVAL;
135         }
136
137         return 0;
138 }
139 EXPORT_SYMBOL(s3c2410_dma_config);
140
141 static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
142                                  struct pl080s_lli *lli,
143                                  dma_addr_t data, int size)
144 {
145         dma_addr_t src, dst;
146         u32 control0, control1;
147
148         switch (chan->source) {
149         case S3C2410_DMASRC_HW:
150                 src = chan->dev_addr;
151                 dst = data;
152                 control0 = PL080_CONTROL_SRC_AHB2;
153                 control0 |= PL080_CONTROL_DST_INCR;
154                 break;
155
156         case S3C2410_DMASRC_MEM:
157                 src = data;
158                 dst = chan->dev_addr;
159                 control0 = PL080_CONTROL_DST_AHB2;
160                 control0 |= PL080_CONTROL_SRC_INCR;
161                 break;
162         default:
163                 BUG();
164         }
165
166         /* note, we do not currently setup any of the burst controls */
167
168         control1 = size >> chan->hw_width;      /* size in no of xfers */
169         control0 |= PL080_CONTROL_PROT_SYS;     /* always in priv. mode */
170         control0 |= PL080_CONTROL_TC_IRQ_EN;    /* always fire IRQ */
171         control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
172         control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
173
174         lli->src_addr = src;
175         lli->dst_addr = dst;
176         lli->next_lli = 0;
177         lli->control0 = control0;
178         lli->control1 = control1;
179 }
180
181 static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
182                                 struct pl080s_lli *lli)
183 {
184         void __iomem *regs = chan->regs;
185
186         pr_debug("%s: LLI %p => regs\n", __func__, lli);
187         show_lli(lli);
188
189         writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
190         writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
191         writel(lli->next_lli, regs + PL080_CH_LLI);
192         writel(lli->control0, regs + PL080_CH_CONTROL);
193         writel(lli->control1, regs + PL080S_CH_CONTROL2);
194 }
195
196 static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
197 {
198         struct s3c64xx_dmac *dmac = chan->dmac;
199         u32 config;
200         u32 bit = chan->bit;
201
202         dbg_showchan(chan);
203
204         pr_debug("%s: clearing interrupts\n", __func__);
205
206         /* clear interrupts */
207         writel(bit, dmac->regs + PL080_TC_CLEAR);
208         writel(bit, dmac->regs + PL080_ERR_CLEAR);
209
210         pr_debug("%s: starting channel\n", __func__);
211
212         config = readl(chan->regs + PL080S_CH_CONFIG);
213         config |= PL080_CONFIG_ENABLE;
214
215         pr_debug("%s: writing config %08x\n", __func__, config);
216         writel(config, chan->regs + PL080S_CH_CONFIG);
217
218         return 0;
219 }
220
221 static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
222 {
223         u32 config;
224         int timeout;
225
226         pr_debug("%s: stopping channel\n", __func__);
227
228         dbg_showchan(chan);
229
230         config = readl(chan->regs + PL080S_CH_CONFIG);
231         config |= PL080_CONFIG_HALT;
232         writel(config, chan->regs + PL080S_CH_CONFIG);
233
234         timeout = 1000;
235         do {
236                 config = readl(chan->regs + PL080S_CH_CONFIG);
237                 pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
238                 if (config & PL080_CONFIG_ACTIVE)
239                         udelay(10);
240                 else
241                         break;
242                 } while (--timeout > 0);
243
244         if (config & PL080_CONFIG_ACTIVE) {
245                 printk(KERN_ERR "%s: channel still active\n", __func__);
246                 return -EFAULT;
247         }
248
249         config = readl(chan->regs + PL080S_CH_CONFIG);
250         config &= ~PL080_CONFIG_ENABLE;
251         writel(config, chan->regs + PL080S_CH_CONFIG);
252
253         return 0;
254 }
255
256 static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
257                                          struct s3c64xx_dma_buff *buf,
258                                          enum s3c2410_dma_buffresult result)
259 {
260         if (chan->callback_fn != NULL)
261                 (chan->callback_fn)(chan, buf->pw, 0, result);
262 }
263
264 static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
265 {
266         dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
267         kfree(buff);
268 }
269
270 static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
271 {
272         struct s3c64xx_dma_buff *buff, *next;
273         u32 config;
274
275         dbg_showchan(chan);
276
277         pr_debug("%s: flushing channel\n", __func__);
278
279         config = readl(chan->regs + PL080S_CH_CONFIG);
280         config &= ~PL080_CONFIG_ENABLE;
281         writel(config, chan->regs + PL080S_CH_CONFIG);
282
283         /* dump all the buffers associated with this channel */
284
285         for (buff = chan->curr; buff != NULL; buff = next) {
286                 next = buff->next;
287                 pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
288
289                 s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
290                 s3c64xx_dma_freebuff(buff);
291         }
292
293         chan->curr = chan->next = chan->end = NULL;
294
295         return 0;
296 }
297
298 int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
299 {
300         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
301
302         WARN_ON(!chan);
303         if (!chan)
304                 return -EINVAL;
305
306         switch (op) {
307         case S3C2410_DMAOP_START:
308                 return s3c64xx_dma_start(chan);
309
310         case S3C2410_DMAOP_STOP:
311                 return s3c64xx_dma_stop(chan);
312
313         case S3C2410_DMAOP_FLUSH:
314                 return s3c64xx_dma_flush(chan);
315
316         /* belive PAUSE/RESUME are no-ops */
317         case S3C2410_DMAOP_PAUSE:
318         case S3C2410_DMAOP_RESUME:
319         case S3C2410_DMAOP_STARTED:
320         case S3C2410_DMAOP_TIMEOUT:
321                 return 0;
322         }
323
324         return -ENOENT;
325 }
326 EXPORT_SYMBOL(s3c2410_dma_ctrl);
327
328 /* s3c2410_dma_enque
329  *
330  */
331
332 int s3c2410_dma_enqueue(unsigned int channel, void *id,
333                         dma_addr_t data, int size)
334 {
335         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
336         struct s3c64xx_dma_buff *next;
337         struct s3c64xx_dma_buff *buff;
338         struct pl080s_lli *lli;
339         unsigned long flags;
340         int ret;
341
342         WARN_ON(!chan);
343         if (!chan)
344                 return -EINVAL;
345
346         buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
347         if (!buff) {
348                 printk(KERN_ERR "%s: no memory for buffer\n", __func__);
349                 return -ENOMEM;
350         }
351
352         lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
353         if (!lli) {
354                 printk(KERN_ERR "%s: no memory for lli\n", __func__);
355                 ret = -ENOMEM;
356                 goto err_buff;
357         }
358
359         pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
360                  __func__, buff, data, lli, (u32)buff->lli_dma, size);
361
362         buff->lli = lli;
363         buff->pw = id;
364
365         s3c64xx_dma_fill_lli(chan, lli, data, size);
366
367         local_irq_save(flags);
368
369         if ((next = chan->next) != NULL) {
370                 struct s3c64xx_dma_buff *end = chan->end;
371                 struct pl080s_lli *endlli = end->lli;
372
373                 pr_debug("enquing onto channel\n");
374
375                 end->next = buff;
376                 endlli->next_lli = buff->lli_dma;
377
378                 if (chan->flags & S3C2410_DMAF_CIRCULAR) {
379                         struct s3c64xx_dma_buff *curr = chan->curr;
380                         lli->next_lli = curr->lli_dma;
381                 }
382
383                 if (next == chan->curr) {
384                         writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
385                         chan->next = buff;
386                 }
387
388                 show_lli(endlli);
389                 chan->end = buff;
390         } else {
391                 pr_debug("enquing onto empty channel\n");
392
393                 chan->curr = buff;
394                 chan->next = buff;
395                 chan->end = buff;
396
397                 s3c64xx_lli_to_regs(chan, lli);
398         }
399
400         local_irq_restore(flags);
401
402         show_lli(lli);
403
404         dbg_showchan(chan);
405         dbg_showbuffs(chan);
406         return 0;
407
408 err_buff:
409         kfree(buff);
410         return ret;
411 }
412
413 EXPORT_SYMBOL(s3c2410_dma_enqueue);
414
415
416 int s3c2410_dma_devconfig(int channel,
417                           enum s3c2410_dmasrc source,
418                           unsigned long devaddr)
419 {
420         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
421         u32 peripheral;
422         u32 config = 0;
423
424         pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
425                  __func__, channel, source, devaddr, chan);
426
427         WARN_ON(!chan);
428         if (!chan)
429                 return -EINVAL;
430
431         peripheral = (chan->peripheral & 0xf);
432         chan->source = source;
433         chan->dev_addr = devaddr;
434
435         pr_debug("%s: peripheral %d\n", __func__, peripheral);
436
437         switch (source) {
438         case S3C2410_DMASRC_HW:
439                 config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
440                 config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
441                 break;
442         case S3C2410_DMASRC_MEM:
443                 config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
444                 config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
445                 break;
446         default:
447                 printk(KERN_ERR "%s: bad source\n", __func__);
448                 return -EINVAL;
449         }
450
451         /* allow TC and ERR interrupts */
452         config |= PL080_CONFIG_TC_IRQ_MASK;
453         config |= PL080_CONFIG_ERR_IRQ_MASK;
454
455         pr_debug("%s: config %08x\n", __func__, config);
456
457         writel(config, chan->regs + PL080S_CH_CONFIG);
458
459         return 0;
460 }
461 EXPORT_SYMBOL(s3c2410_dma_devconfig);
462
463
464 int s3c2410_dma_getposition(unsigned int channel,
465                             dma_addr_t *src, dma_addr_t *dst)
466 {
467         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
468
469         WARN_ON(!chan);
470         if (!chan)
471                 return -EINVAL;
472
473         if (src != NULL)
474                 *src = readl(chan->regs + PL080_CH_SRC_ADDR);
475
476         if (dst != NULL)
477                 *dst = readl(chan->regs + PL080_CH_DST_ADDR);
478
479         return 0;
480 }
481 EXPORT_SYMBOL(s3c2410_dma_getposition);
482
483 /* s3c2410_request_dma
484  *
485  * get control of an dma channel
486 */
487
488 int s3c2410_dma_request(unsigned int channel,
489                         struct s3c2410_dma_client *client,
490                         void *dev)
491 {
492         struct s3c2410_dma_chan *chan;
493         unsigned long flags;
494
495         pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
496                  channel, client->name, dev);
497
498         local_irq_save(flags);
499
500         chan = s3c64xx_dma_map_channel(channel);
501         if (chan == NULL) {
502                 local_irq_restore(flags);
503                 return -EBUSY;
504         }
505
506         dbg_showchan(chan);
507
508         chan->client = client;
509         chan->in_use = 1;
510         chan->peripheral = channel;
511
512         local_irq_restore(flags);
513
514         /* need to setup */
515
516         pr_debug("%s: channel initialised, %p\n", __func__, chan);
517
518         return chan->number | DMACH_LOW_LEVEL;
519 }
520
521 EXPORT_SYMBOL(s3c2410_dma_request);
522
523 /* s3c2410_dma_free
524  *
525  * release the given channel back to the system, will stop and flush
526  * any outstanding transfers, and ensure the channel is ready for the
527  * next claimant.
528  *
529  * Note, although a warning is currently printed if the freeing client
530  * info is not the same as the registrant's client info, the free is still
531  * allowed to go through.
532 */
533
534 int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
535 {
536         struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
537         unsigned long flags;
538
539         if (chan == NULL)
540                 return -EINVAL;
541
542         local_irq_save(flags);
543
544         if (chan->client != client) {
545                 printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
546                        channel, chan->client, client);
547         }
548
549         /* sort out stopping and freeing the channel */
550
551
552         chan->client = NULL;
553         chan->in_use = 0;
554
555         if (!(channel & DMACH_LOW_LEVEL))
556                 s3c_dma_chan_map[channel] = NULL;
557
558         local_irq_restore(flags);
559
560         return 0;
561 }
562
563 EXPORT_SYMBOL(s3c2410_dma_free);
564
565 static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
566 {
567         struct s3c64xx_dmac *dmac = pw;
568         struct s3c2410_dma_chan *chan;
569         enum s3c2410_dma_buffresult res;
570         u32 tcstat, errstat;
571         u32 bit;
572         int offs;
573
574         tcstat = readl(dmac->regs + PL080_TC_STATUS);
575         errstat = readl(dmac->regs + PL080_ERR_STATUS);
576
577         for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
578                 struct s3c64xx_dma_buff *buff;
579
580                 if (!(errstat & bit) && !(tcstat & bit))
581                         continue;
582
583                 chan = dmac->channels + offs;
584                 res = S3C2410_RES_ERR;
585
586                 if (tcstat & bit) {
587                         writel(bit, dmac->regs + PL080_TC_CLEAR);
588                         res = S3C2410_RES_OK;
589                 }
590
591                 if (errstat & bit)
592                         writel(bit, dmac->regs + PL080_ERR_CLEAR);
593
594                 /* 'next' points to the buffer that is next to the
595                  * currently active buffer.
596                  * For CIRCULAR queues, 'next' will be same as 'curr'
597                  * when 'end' is the active buffer.
598                  */
599                 buff = chan->curr;
600                 while (buff && buff != chan->next
601                                 && buff->next != chan->next)
602                         buff = buff->next;
603
604                 if (!buff)
605                         BUG();
606
607                 if (buff == chan->next)
608                         buff = chan->end;
609
610                 s3c64xx_dma_bufffdone(chan, buff, res);
611
612                 /* Free the node and update curr, if non-circular queue */
613                 if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
614                         chan->curr = buff->next;
615                         s3c64xx_dma_freebuff(buff);
616                 }
617
618                 /* Update 'next' */
619                 buff = chan->next;
620                 if (chan->next == chan->end) {
621                         chan->next = chan->curr;
622                         if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
623                                 chan->end = NULL;
624                 } else {
625                         chan->next = buff->next;
626                 }
627         }
628
629         return IRQ_HANDLED;
630 }
631
632 static struct sysdev_class dma_sysclass = {
633         .name           = "s3c64xx-dma",
634 };
635
636 static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
637                              int irq, unsigned int base)
638 {
639         struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
640         struct s3c64xx_dmac *dmac;
641         char clkname[16];
642         void __iomem *regs;
643         void __iomem *regptr;
644         int err, ch;
645
646         dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
647         if (!dmac) {
648                 printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
649                 return -ENOMEM;
650         }
651
652         dmac->sysdev.id = chno / 8;
653         dmac->sysdev.cls = &dma_sysclass;
654
655         err = sysdev_register(&dmac->sysdev);
656         if (err) {
657                 printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
658                 goto err_alloc;
659         }
660
661         regs = ioremap(base, 0x200);
662         if (!regs) {
663                 printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
664                 err = -ENXIO;
665                 goto err_dev;
666         }
667
668         snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
669
670         dmac->clk = clk_get(NULL, clkname);
671         if (IS_ERR(dmac->clk)) {
672                 printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
673                 err = PTR_ERR(dmac->clk);
674                 goto err_map;
675         }
676
677         clk_enable(dmac->clk);
678
679         dmac->regs = regs;
680         dmac->chanbase = chbase;
681         dmac->channels = chptr;
682
683         err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
684         if (err < 0) {
685                 printk(KERN_ERR "%s: failed to get irq\n", __func__);
686                 goto err_clk;
687         }
688
689         regptr = regs + PL080_Cx_BASE(0);
690
691         for (ch = 0; ch < 8; ch++, chno++, chptr++) {
692                 printk(KERN_INFO "%s: registering DMA %d (%p)\n",
693                        __func__, chno, regptr);
694
695                 chptr->bit = 1 << ch;
696                 chptr->number = chno;
697                 chptr->dmac = dmac;
698                 chptr->regs = regptr;
699                 regptr += PL008_Cx_STRIDE;
700         }
701
702         /* for the moment, permanently enable the controller */
703         writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
704
705         printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
706
707         return 0;
708
709 err_clk:
710         clk_disable(dmac->clk);
711         clk_put(dmac->clk);
712 err_map:
713         iounmap(regs);
714 err_dev:
715         sysdev_unregister(&dmac->sysdev);
716 err_alloc:
717         kfree(dmac);
718         return err;
719 }
720
721 static int __init s3c64xx_dma_init(void)
722 {
723         int ret;
724
725         printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
726
727         dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
728         if (!dma_pool) {
729                 printk(KERN_ERR "%s: failed to create pool\n", __func__);
730                 return -ENOMEM;
731         }
732
733         ret = sysdev_class_register(&dma_sysclass);
734         if (ret) {
735                 printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
736                 return -ENOMEM;
737         }
738
739         /* Set all DMA configuration to be DMA, not SDMA */
740         writel(0xffffff, S3C_SYSREG(0x110));
741
742         /* Register standard DMA controlers */
743         s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
744         s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
745
746         return 0;
747 }
748
749 arch_initcall(s3c64xx_dma_init);