Ticket #1234: glamo-fb-dma.patch.txt

File glamo-fb-dma.patch.txt, 17.5 KB (added by dodji@…, 11 years ago)

initial implementation of the dma based pixmap migration

Line 
1Index: linux-2.6.24/arch/arm/mach-s3c2440/mach-gta02.c
2===================================================================
3--- linux-2.6.24.orig/arch/arm/mach-s3c2440/mach-gta02.c        2008-02-14 15:33:55.000000000 +0100
4+++ linux-2.6.24/arch/arm/mach-s3c2440/mach-gta02.c     2008-02-14 18:08:30.000000000 +0100
5@@ -638,8 +638,8 @@
6        },
7        [2] = {
8                .flags = IORESOURCE_DMA,
9-               .start = 0, /* Channel 0 for SDI */
10-               .end = 0,
11+               .start = 2, /* Channel 2 for SDI */
12+               .end = 2,
13        },
14 };
15 
16Index: linux-2.6.24/drivers/mfd/glamo/glamo-fb.c
17===================================================================
18--- linux-2.6.24.orig/drivers/mfd/glamo/glamo-fb.c      2008-02-14 15:33:54.000000000 +0100
19+++ linux-2.6.24/drivers/mfd/glamo/glamo-fb.c   2008-02-17 21:06:43.000000000 +0100
20@@ -27,6 +27,7 @@
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/delay.h>
24+#include <linux/console.h>
25 #include <linux/fb.h>
26 #include <linux/init.h>
27 #include <linux/vmalloc.h>
28@@ -40,6 +41,7 @@
29 #include <asm/io.h>
30 #include <asm/uaccess.h>
31 #include <asm/div64.h>
32+#include <asm/dma.h>
33 
34 #ifdef CONFIG_PM
35 #include <linux/pm.h>
36@@ -50,28 +52,51 @@
37 #include "glamo-regs.h"
38 #include "glamo-core.h"
39 
40-#ifdef DEBUG
41-#define GLAMO_LOG(...)
42+#define DEBUG 1
43+
44+#ifndef DEBUG
45+#define GLAMO_LOG(format,arg...)
46 #else
47-#define GLAMO_LOG(...) \
48+#define GLAMO_LOG(format,arg...) \
49 do { \
50-       printk(KERN_DEBUG "in %s:%s:%d", __FILE__, __func__, __LINE__); \
51-       printk(KERN_DEBUG __VA_ARGS__); \
52+       printk(KERN_INFO "in %s:%s:%d:" format, \
53+              __FILE__, __func__, __LINE__, ## arg); \
54 } while (0);
55 #endif
56 
57 
58 #define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
59 
60+struct pixmap_dma_context {
61+       u_int32_t channel;
62+       u_int32_t en;
63+       u_int32_t datum_size;
64+       char do_dma_write; /*write to glamo ?*/
65+       dma_addr_t vram_dma_addr;
66+       void *io_dma_buf;
67+       dma_addr_t io_dma_buf_ba; /*bus address of io_dma_buf*/
68+       int io_dma_buf_size; /*buf size in bytes*/
69+       int io_dma_len;
70+       int pixmap_vram_addr;
71+       struct glamofb_pixmap *pixmap;
72+       int vram_pitch;
73+       int cur_line;
74+       struct work_struct pixmap_line_dma_work;
75+       wait_queue_head_t pixmap_xfer_wait;
76+};
77+
78 struct glamofb_handle {
79        struct fb_info *fb;
80        struct device *dev;
81        struct resource *reg;
82        struct resource *fb_res;
83+       struct resource *dma_res;
84        char __iomem *base;
85        struct glamofb_platform_data *mach_info;
86        char __iomem *cursor_addr;
87        u_int32_t pseudo_pal[16];
88+       struct glamofb_upload_pixmap_info p_info;
89+       struct pixmap_dma_context dma_ctxt;
90 };
91 
92 /* 'sibling' spi device for lcm init */
93@@ -117,6 +142,10 @@
94        { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */
95 };
96 
97+static struct s3c2410_dma_client glamofb_dma_client = {
98+       .name           = "glamo-fb",
99+};
100+
101 static int glamofb_run_script(struct glamofb_handle *glamo,
102                                struct glamo_script *script, int len)
103 {
104@@ -474,6 +503,7 @@
105        return 0;
106 }
107 
108+#if 0
109 static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
110 {
111        struct glamofb_handle *glamo = info->par;
112@@ -545,6 +575,7 @@
113                }
114        }
115 }
116+#endif
117 
118 static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
119 {
120@@ -601,12 +632,352 @@
121 }
122 EXPORT_SYMBOL_GPL(glamofb_cmd_write);
123 
124+static int trigger_dma(struct glamofb_handle *glamofb,
125+                      char do_dma_write/*write to/read from glamo*/,
126+                      u_int32_t dma_datum_size,
127+                      unsigned vram_addr,
128+                      dma_addr_t io_dma_buf,
129+                      int io_dma_len,
130+                      char do_sleep);
131+
132+static void dma_done(struct s3c2410_dma_chan *channel,
133+                     void *glamofb_handle,
134+                     int size,
135+                     enum s3c2410_dma_buffresult result)
136+{
137+       struct glamofb_handle *glamofb = glamofb_handle;
138+       GLAMO_LOG("enter, size:%d, result:%d\n", size, result);
139+       if (!channel || !glamofb) {
140+               printk(KERN_ERR "got null channel of glamofb\n");
141+               goto out;
142+       }
143+       /*
144+        * TODO:dump error log in case of error
145+        * then go test the beast.
146+        */
147+       if (result != S3C2410_RES_OK) {
148+               printk(KERN_ERR "DMA xfer failed:%d\n", result);
149+               goto out;
150+       }
151+       printk(KERN_INFO "DMA xfer of line:%d went OK.\n",
152+              glamofb->dma_ctxt.cur_line);
153+       glamofb->dma_ctxt.cur_line++;
154+       if (glamofb->dma_ctxt.cur_line
155+           < glamofb->dma_ctxt.pixmap->height) {
156+               printk("scheduling DMA of pixmap line:%d ...\n",
157+                      glamofb->dma_ctxt.cur_line);
158+               schedule_work(&glamofb->dma_ctxt.pixmap_line_dma_work);
159+       } else {
160+               GLAMO_LOG("all lines got DMA'ed OK!!\n");
161+               wake_up_interruptible(&glamofb->dma_ctxt.pixmap_xfer_wait);
162+               GLAMO_LOG("woke up\n");
163+       }
164+
165+out:
166+       GLAMO_LOG("leave\n");
167+}
168+
169+static void do_pixmap_line_dma_work(struct work_struct *work)
170+{
171+       struct pixmap_dma_context *dma_ctxt =
172+               container_of(work,
173+                            struct pixmap_dma_context,
174+                            pixmap_line_dma_work);
175+       struct glamofb_handle *glamofb =
176+               container_of(dma_ctxt,
177+                            struct glamofb_handle,
178+                            dma_ctxt);
179+
180+       GLAMO_LOG("enter:glamofb:%p, glamofb->vram_pitch:%d\n",
181+                 glamofb, glamofb->dma_ctxt.vram_pitch);
182+
183+       if (glamofb->dma_ctxt.cur_line
184+           < glamofb->dma_ctxt.pixmap->height) {
185+               unsigned from, to;
186+               int vram_pitch = glamofb->dma_ctxt.vram_pitch / 8;
187+               int err = -1;
188+               int line_len = glamofb->dma_ctxt.pixmap->width;
189+               line_len *= glamofb->dma_ctxt.pixmap->bits_per_pixel / 8;
190+               from = glamofb->dma_ctxt.io_dma_buf_ba
191+                       + glamofb->dma_ctxt.pixmap->pitch;
192+               to = glamofb->dma_ctxt.vram_dma_addr + vram_pitch;
193+               GLAMO_LOG("going to trigger xfer of line:%d "
194+                         "from:%#x, to:%#x, with vram_pitch:%d\n",
195+                         glamofb->dma_ctxt.cur_line, from, to, vram_pitch);
196+               err = trigger_dma(glamofb, 1, 1, to, from, line_len, 0);
197+               if (err) {
198+                       printk(KERN_ERR "error: failed to trigger dma\n in "
199+                                       "dma_done:%d\n", err);
200+               }
201+       } else {
202+               GLAMO_LOG("all lines got DMA'ed already!!\n");
203+       }
204+       GLAMO_LOG("leave\n");
205+}
206+
207+static int trigger_dma(struct glamofb_handle *glamofb,
208+                      char do_dma_write/*write to/read from glamo*/,
209+                      u_int32_t dma_datum_size,
210+                      unsigned vram_addr,
211+                      dma_addr_t io_dma_buf,
212+                      int io_dma_len,
213+                      char do_sleep)
214+{
215+       int err=-1;
216+       int dcon;
217+
218+       GLAMO_LOG("enter, dma channel:%d, dma_datum_size:%d,\n"
219+                 "vram_addr:%#x, io_dma_buf:%#lx, io_dma_len:%d\n",
220+                 glamofb->dma_ctxt.channel,
221+                 dma_datum_size,
222+                 vram_addr,
223+                 io_dma_buf,
224+                 io_dma_len);
225+       if (!glamofb) {
226+               printk(KERN_ERR "got NULL glamofb");
227+               goto out;
228+       }
229+       glamofb->dma_ctxt.do_dma_write = do_dma_write;
230+       glamofb->dma_ctxt.datum_size = dma_datum_size;
231+       glamofb->dma_ctxt.vram_dma_addr = vram_addr;
232+       glamofb->dma_ctxt.io_dma_buf_ba = io_dma_buf;
233+       glamofb->dma_ctxt.io_dma_len = io_dma_len;
234+       glamofb->dma_ctxt.en = 1;
235+
236+       if (glamofb->dma_ctxt.do_dma_write) {
237+               err = s3c2410_dma_devconfig(glamofb->dma_ctxt.channel,
238+                                           S3C2410_DMASRC_MEM,
239+                                           0,
240+                                           glamofb->dma_ctxt.vram_dma_addr);
241+               if (err) {
242+                       printk(KERN_ERR "failed to setup dma source:%d\n",
243+                              err);
244+                       goto out;
245+               }
246+       } else {
247+               err = s3c2410_dma_devconfig(glamofb->dma_ctxt.channel,
248+                                           S3C2410_DMASRC_HW,
249+                                           0,
250+                                           glamofb->dma_ctxt.vram_dma_addr);
251+               if (err) {
252+                       printk(KERN_ERR "failed to setup dma source:%d\n",
253+                              err);
254+                       goto out;
255+               }
256+       }
257+       dcon = glamofb->dma_ctxt.io_dma_len;
258+       dcon |= S3C2410_DCON_INTREQ;
259+       dcon |= S3C2410_DCON_SERVMOD_WHOLE;
260+       err = s3c2410_dma_config(glamofb->dma_ctxt.channel,
261+                                glamofb->dma_ctxt.datum_size,
262+                                dcon);
263+       if (err) {
264+               printk(KERN_ERR "failed to setup dma size and channel\n");
265+               goto out;
266+       }
267+       err = s3c2410_dma_set_buffdone_fn(glamofb->dma_ctxt.channel,
268+                                         dma_done);
269+       if (err) {
270+               printk(KERN_ERR "failed to setup dma buffdone\n");
271+               goto out;
272+       }
273+       err = s3c2410_dma_setflags(glamofb->dma_ctxt.channel,
274+                                  S3C2410_DMAF_AUTOSTART);
275+       if (err) {
276+               printk(KERN_ERR "failed to setup dma operation\n");
277+               goto out;
278+       }
279+       err = s3c2410_dma_enqueue(glamofb->dma_ctxt.channel,
280+                                 glamofb,
281+                                 glamofb->dma_ctxt.io_dma_buf_ba,
282+                                 glamofb->dma_ctxt.io_dma_len);
283+       if (err) {
284+               printk(KERN_ERR "failed to enqueue dma buffer\n");
285+               goto out;
286+       }
287+       /*s3c2410_dma_ctrl(glamofb->dma_ctxt.channel, S3C2410_DMAOP_START);*/
288+       if (do_sleep) {
289+               wait_event_interruptible(glamofb->dma_ctxt.pixmap_xfer_wait,
290+                                        glamofb->dma_ctxt.cur_line
291+                                        >= glamofb->dma_ctxt.pixmap->height);
292+       }
293+       err = 0;
294+out:
295+       GLAMO_LOG("leave\n");
296+       return err;
297+}
298+
299+static int trigger_pixmap_dma_to_vram(struct glamofb_handle *glamofb,
300+                                     struct glamofb_pixmap *pixmap,
301+                                     unsigned vram_addr,
302+                                     unsigned vram_pitch,
303+                                     dma_addr_t pixmap_buf,
304+                                     int pixmap_buf_len)
305+{
306+       int err = -1, line_len;
307+
308+       GLAMO_LOG("enter, glamofb:%p, pixmap:%p\n", glamofb, pixmap);
309+
310+       if (!pixmap || ! glamofb) {
311+               printk(KERN_ERR "got NULL pixmap or glamofb."
312+                               " glamofb:%p, pixmap:%p\n",
313+                      glamofb, pixmap);
314+               goto out;
315+       }
316+       glamofb->dma_ctxt.pixmap = pixmap;
317+       glamofb->dma_ctxt.vram_pitch = vram_pitch;
318+       glamofb->dma_ctxt.cur_line = 0;
319+       line_len = pixmap->width * pixmap->bits_per_pixel / 8;
320+       /*trigger the copy of the first line of the pixmap to vram*/
321+       err = trigger_dma(glamofb, 1, 1, vram_addr,
322+                          pixmap_buf, line_len, 1/*sleep*/);
323+out:
324+       GLAMO_LOG("leave. err:%d\n", err);
325+       return err;
326+}
327+
328+static int dma_upload_to_vram(struct glamofb_handle *glamofb,
329+                             struct glamofb_pixmap  *pixmap/*pxm in vram*/,
330+                             unsigned to /*offset in glamo vram*/,
331+                             unsigned vram_pitch)
332+{
333+       void __user *pixmap_addr;
334+       char *screen_base=NULL;
335+       int err = -1;
336+       /*
337+        * size of the rectangular region containing
338+        * which width equals the pixmap pitch, and that
339+        * contains the pixmap
340+        */
341+       int pixmap_region_size;
342+
343+       if (!pixmap || !glamofb) {
344+               printk(KERN_ERR "(glamofb_dma_upload_to_vram) "
345+                               "failed sanity\n");
346+               goto out;
347+       }
348+
349+       GLAMO_LOG("enter. glamofb:%p, "
350+                 "pixmap(pitch,w,h,bpp,@):(%d,%d,%d,%d,%#x),"
351+                 "to:%#x, vram_pitch:%d\n",
352+                 glamofb,
353+                 pixmap->pitch, pixmap->width,
354+                 pixmap->height,
355+                 pixmap->bits_per_pixel,
356+                 (unsigned int)pixmap->address,
357+                 to, vram_pitch);
358+       /*
359+        * now copy the pixmap into the in kernel buffer,
360+        * and start the DMA transfers for each DMA buffer lines.
361+        */
362+       pixmap_addr = (void __user*)pixmap->address;
363+       pixmap_region_size =
364+               pixmap->pitch*pixmap->height*pixmap->bits_per_pixel/2;
365+       GLAMO_LOG("going to copy %d bytes of wide pixmap region "
366+                 "from user space, starting at %#x, into %#x\n",
367+                 pixmap_region_size, (unsigned)pixmap_addr,
368+                 (unsigned)glamofb->dma_ctxt.io_dma_buf);
369+       err = copy_from_user(glamofb->dma_ctxt.io_dma_buf,
370+                            pixmap_addr,
371+                            pixmap_region_size);
372+       if (err) {
373+               printk(KERN_ERR "failed to copy pixmap to kernel\n");
374+               goto out;
375+       }
376+       GLAMO_LOG("did copy okay\n");
377+       screen_base = (char*)glamofb->fb_res->start;
378+       GLAMO_LOG("screen_base:%#x, to:%#x",
379+                 (unsigned)screen_base, to);
380+       err = trigger_pixmap_dma_to_vram(glamofb,
381+                                        pixmap,
382+                                        (unsigned)screen_base+to,
383+                                        vram_pitch,
384+                                        glamofb->dma_ctxt.io_dma_buf_ba,
385+                                        pixmap_region_size);
386+       if (err) {
387+               printk(KERN_ERR "dma xfer failed\n");
388+               goto out;
389+       } else {
390+               GLAMO_LOG("dma xfer triggered okay\n");
391+       }
392+
393+out:
394+       GLAMO_LOG("leave. err:%d\n", err);
395+       return err;
396+}
397+
398+void glamofb_log_pixmap(struct glamofb_pixmap *pixmap)
399+{
400+       printk(KERN_INFO "(WxH,p,bpp,address):(%dx%d,%d,%d,%#x)\n",
401+              pixmap->width, pixmap->height,
402+              pixmap->pitch, pixmap->bits_per_pixel,
403+              (unsigned int)pixmap->address);
404+}
405+
406+void glamofb_log_upload_pixmap_info(struct glamofb_upload_pixmap_info *info)
407+{
408+       printk(KERN_INFO "pixmap: ");
409+       glamofb_log_pixmap(&info->pixmap);
410+       printk(KERN_INFO "(dest_offset, dest_pitch):(%d,%d)\n",
411+              info->dest_offset,
412+              info->dest_pitch);
413+}
414+
415+static int glamofb_ioctl (struct fb_info *info,
416+                         unsigned int cmd,
417+                         unsigned long arg)
418+{
419+       int err = -1;
420+       void __user *argp = (void __user*)arg;
421+       struct glamofb_handle *glamofb = info->par;
422+
423+       GLAMO_LOG("enter, cmd:%#x, glamofb:%p\n", cmd, glamofb);
424+
425+       acquire_console_sem();
426+
427+       switch (cmd) {
428+               case FBIO_GLAMO_UPLOAD_PIXMAP_TO_VRAM:
429+                       err = copy_from_user(&glamofb->p_info,
430+                                            argp,
431+                                            sizeof(glamofb->p_info));
432+                       if (err) {
433+                               printk(KERN_ERR "failed to copy "
434+                                               "ioctl parameters\n");
435+                               goto out;
436+                       }
437+                       glamofb_log_upload_pixmap_info(&glamofb->p_info);
438+                       err = dma_upload_to_vram(glamofb,
439+                                                &glamofb->p_info.pixmap,
440+                                                glamofb->p_info.dest_offset,
441+                                                glamofb->p_info.dest_pitch);
442+                       if (err) {
443+                               printk(KERN_ERR "upload to vram failed\n");
444+                               goto out;
445+                       }
446+                       break;
447+               default:
448+                       printk(KERN_ERR "unknown ioctl received in "
449+                                       "glamo-fb:%d\n",
450+                               cmd);
451+                       err = -EINVAL;
452+                       goto out;
453+       }
454+       err = 0;
455+
456+out:
457+       GLAMO_LOG("leave. err:%d\n", err);
458+       release_console_sem();
459+       return err;
460+}
461+
462 static struct fb_ops glamofb_ops = {
463        .owner          = THIS_MODULE,
464        .fb_check_var   = glamofb_check_var,
465        .fb_set_par     = glamofb_set_par,
466        .fb_blank       = glamofb_blank,
467        .fb_setcolreg   = glamofb_setcolreg,
468+       .fb_ioctl =       glamofb_ioctl,
469+       .fb_compat_ioctl = glamofb_ioctl,
470        //.fb_cursor    = glamofb_cursor,
471        .fb_fillrect    = cfb_fillrect,
472        .fb_copyarea    = cfb_copyarea,
473@@ -752,6 +1123,44 @@
474        printk(KERN_INFO "fb%d: %s frame buffer device\n",
475                fbinfo->node, fbinfo->fix.id);
476 
477+       /*DMA setup*/
478+       glamofb->dma_res =
479+               platform_get_resource_byname(pdev, IORESOURCE_DMA,
480+                                            "glamo-dma");
481+       if (!glamofb->dma_res) {
482+               printk(KERN_ERR "failed to get DMA resource\n");
483+               goto out;
484+       }
485+       printk(KERN_INFO "got DMA resource OK\n");
486+       glamofb->dma_ctxt.channel = glamofb->dma_res->start;
487+       GLAMO_LOG("dma channel:%d\n", glamofb->dma_ctxt.channel);
488+       glamofb->dma_ctxt.en = 0;
489+       glamofb->dma_ctxt.io_dma_buf_size = 480*640*2;
490+       glamofb->dma_ctxt.io_dma_buf =
491+               dma_alloc_writecombine(&pdev->dev,
492+                                      glamofb->dma_ctxt.io_dma_buf_size,
493+                                      &glamofb->dma_ctxt.io_dma_buf_ba,
494+                                      GFP_KERNEL|GFP_DMA);
495+       if (!glamofb->dma_ctxt.io_dma_buf) {
496+               printk(KERN_ERR "failed to alloc dma buf of size %d\n",
497+                      glamofb->dma_ctxt.io_dma_buf_size);
498+               goto out;
499+       } else {
500+               printk(KERN_INFO "allocated dma io buffer at %#x\n",
501+                      (unsigned)glamofb->dma_ctxt.io_dma_buf);
502+       }
503+       if (s3c2410_dma_request(glamofb->dma_ctxt.channel,
504+                               &glamofb_dma_client,
505+                               NULL)) {
506+               printk("unable to get DMA channel for channel num %d",
507+                      glamofb->dma_ctxt.channel);
508+               goto out;
509+       }
510+       INIT_WORK(&glamofb->dma_ctxt.pixmap_line_dma_work,
511+                 do_pixmap_line_dma_work);
512+       init_waitqueue_head(&glamofb->dma_ctxt.pixmap_xfer_wait);
513+
514+out:
515        return 0;
516 
517 out_unmap_fb:
518Index: linux-2.6.24/include/linux/glamofb.h
519===================================================================
520--- linux-2.6.24.orig/include/linux/glamofb.h   2008-02-14 15:33:54.000000000 +0100
521+++ linux-2.6.24/include/linux/glamofb.h        2008-02-15 13:17:24.000000000 +0100
522@@ -33,6 +33,23 @@
523        int             (*glamo_irq_is_wired)(void);
524 };
525 
526+struct glamofb_pixmap {
527+       unsigned int pitch;
528+       unsigned int width;
529+       unsigned int height;
530+       unsigned int bits_per_pixel;
531+       char *address;
532+};
533+
534+struct glamofb_upload_pixmap_info {
535+       struct glamofb_pixmap pixmap;
536+       unsigned int dest_offset;/*offset in glamo vram*/
537+       unsigned int  dest_pitch;
538+};
539+
540+#define FBIO_GLAMO_UPLOAD_PIXMAP_TO_VRAM \
541+       _IOW('F', 0x19, struct glamofb_upload_pixmap_info)
542+
543 void glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
544 int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
545 
546Index: linux-2.6.24/arch/arm/plat-s3c24xx/dma.c
547===================================================================
548--- linux-2.6.24.orig/arch/arm/plat-s3c24xx/dma.c       2008-02-17 01:01:03.000000000 +0100
549+++ linux-2.6.24/arch/arm/plat-s3c24xx/dma.c    2008-02-17 01:01:29.000000000 +0100
550@@ -377,6 +377,7 @@
551        tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
552        tmp &= ~S3C2410_DMASKTRIG_STOP;
553        tmp |= S3C2410_DMASKTRIG_ON;
554+       tmp |= S3C2410_DMASKTRIG_SWTRIG;
555        dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
556 
557        pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
558@@ -1078,7 +1079,7 @@
559                return -EINVAL;
560        }
561 
562-       dcon |= S3C2410_DCON_HWTRIG;
563+       /*dcon |= S3C2410_DCON_HWTRIG;*/
564        dcon |= S3C2410_DCON_INTREQ;
565 
566        pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
567@@ -1165,8 +1166,10 @@
568 {
569        struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
570 
571-       if (chan == NULL)
572+       if (chan == NULL) {
573+               printk(KERN_ERR "got NULL chan\n");
574                return -EINVAL;
575+       }
576 
577        pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
578                 __FUNCTION__, (int)source, hwcfg, devaddr);
579Index: linux-2.6.24/drivers/mfd/glamo/glamo-core.c
580===================================================================
581--- linux-2.6.24.orig/drivers/mfd/glamo/glamo-core.c    2008-02-14 18:09:08.000000000 +0100
582+++ linux-2.6.24/drivers/mfd/glamo/glamo-core.c 2008-02-15 15:06:33.000000000 +0100
583@@ -233,10 +233,19 @@
584                .end    = GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1,
585                .flags  = IORESOURCE_MEM,
586        },
587+       {
588+               .name = "glamo-dma",
589+               .start = 0, /* Channel 0 for XDREQ */
590+               .end   = 0,
591+               .flags = IORESOURCE_DMA
592+       },
593 };
594 
595 static struct platform_device glamo_fb_dev = {
596        .name           = "glamo-fb",
597+       .dev            = {
598+               .coherent_dma_mask      = 0xffffffff,
599+       },
600        .resource       = glamo_fb_resources,
601        .num_resources  = ARRAY_SIZE(glamo_fb_resources),
602 };
603Index: linux-2.6.24/include/asm-arm/arch-s3c2410/dma.h
604===================================================================
605--- linux-2.6.24.orig/include/asm-arm/arch-s3c2410/dma.h        2008-01-24 23:58:37.000000000 +0100
606+++ linux-2.6.24/include/asm-arm/arch-s3c2410/dma.h     2008-02-16 22:00:40.000000000 +0100
607@@ -342,6 +342,8 @@
608 #define S3C2410_DCON_SYNC_HCLK  (1<<30)
609 
610 #define S3C2410_DCON_INTREQ     (1<<29)
611+#define S3C2410_DCON_SERVMOD_WHOLE   (1<<27)
612+#define S3C2410_DCON_SERVMOD_SINGLE   (0<<27)
613 
614 #define S3C2410_DCON_CH0_XDREQ0        (0<<24)
615 #define S3C2410_DCON_CH0_UART0 (1<<24)