drm/radeon/kms: enable use of unmappable VRAM V2
[pandora-kernel.git] / drivers / media / video / videobuf-dma-contig.c
1 /*
2  * helper functions for physically contiguous capture buffers
3  *
4  * The functions support hardware lacking scatter gather support
5  * (i.e. the buffers must be linear in physical memory)
6  *
7  * Copyright (c) 2008 Magnus Damm
8  *
9  * Based on videobuf-vmalloc.c,
10  * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
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 as published by
14  * the Free Software Foundation; either version 2
15  */
16
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/mm.h>
20 #include <linux/pagemap.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/sched.h>
23 #include <media/videobuf-dma-contig.h>
24
25 struct videobuf_dma_contig_memory {
26         u32 magic;
27         void *vaddr;
28         dma_addr_t dma_handle;
29         unsigned long size;
30         int is_userptr;
31 };
32
33 #define MAGIC_DC_MEM 0x0733ac61
34 #define MAGIC_CHECK(is, should)                                             \
35         if (unlikely((is) != (should))) {                                   \
36                 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
37                 BUG();                                                      \
38         }
39
40 static void
41 videobuf_vm_open(struct vm_area_struct *vma)
42 {
43         struct videobuf_mapping *map = vma->vm_private_data;
44
45         dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
46                 map, map->count, vma->vm_start, vma->vm_end);
47
48         map->count++;
49 }
50
51 static void videobuf_vm_close(struct vm_area_struct *vma)
52 {
53         struct videobuf_mapping *map = vma->vm_private_data;
54         struct videobuf_queue *q = map->q;
55         int i;
56
57         dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
58                 map, map->count, vma->vm_start, vma->vm_end);
59
60         map->count--;
61         if (0 == map->count) {
62                 struct videobuf_dma_contig_memory *mem;
63
64                 dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q);
65                 mutex_lock(&q->vb_lock);
66
67                 /* We need first to cancel streams, before unmapping */
68                 if (q->streaming)
69                         videobuf_queue_cancel(q);
70
71                 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
72                         if (NULL == q->bufs[i])
73                                 continue;
74
75                         if (q->bufs[i]->map != map)
76                                 continue;
77
78                         mem = q->bufs[i]->priv;
79                         if (mem) {
80                                 /* This callback is called only if kernel has
81                                    allocated memory and this memory is mmapped.
82                                    In this case, memory should be freed,
83                                    in order to do memory unmap.
84                                  */
85
86                                 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
87
88                                 /* vfree is not atomic - can't be
89                                    called with IRQ's disabled
90                                  */
91                                 dev_dbg(map->q->dev, "buf[%d] freeing %p\n",
92                                         i, mem->vaddr);
93
94                                 dma_free_coherent(q->dev, mem->size,
95                                                   mem->vaddr, mem->dma_handle);
96                                 mem->vaddr = NULL;
97                         }
98
99                         q->bufs[i]->map   = NULL;
100                         q->bufs[i]->baddr = 0;
101                 }
102
103                 kfree(map);
104
105                 mutex_unlock(&q->vb_lock);
106         }
107 }
108
109 static const struct vm_operations_struct videobuf_vm_ops = {
110         .open     = videobuf_vm_open,
111         .close    = videobuf_vm_close,
112 };
113
114 /**
115  * videobuf_dma_contig_user_put() - reset pointer to user space buffer
116  * @mem: per-buffer private videobuf-dma-contig data
117  *
118  * This function resets the user space pointer
119  */
120 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
121 {
122         mem->is_userptr = 0;
123         mem->dma_handle = 0;
124         mem->size = 0;
125 }
126
127 /**
128  * videobuf_dma_contig_user_get() - setup user space memory pointer
129  * @mem: per-buffer private videobuf-dma-contig data
130  * @vb: video buffer to map
131  *
132  * This function validates and sets up a pointer to user space memory.
133  * Only physically contiguous pfn-mapped memory is accepted.
134  *
135  * Returns 0 if successful.
136  */
137 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
138                                         struct videobuf_buffer *vb)
139 {
140         struct mm_struct *mm = current->mm;
141         struct vm_area_struct *vma;
142         unsigned long prev_pfn, this_pfn;
143         unsigned long pages_done, user_address;
144         unsigned int offset;
145         int ret;
146
147         offset = vb->baddr & ~PAGE_MASK;
148         mem->size = PAGE_ALIGN(vb->size + offset);
149         mem->is_userptr = 0;
150         ret = -EINVAL;
151
152         down_read(&mm->mmap_sem);
153
154         vma = find_vma(mm, vb->baddr);
155         if (!vma)
156                 goto out_up;
157
158         if ((vb->baddr + mem->size) > vma->vm_end)
159                 goto out_up;
160
161         pages_done = 0;
162         prev_pfn = 0; /* kill warning */
163         user_address = vb->baddr;
164
165         while (pages_done < (mem->size >> PAGE_SHIFT)) {
166                 ret = follow_pfn(vma, user_address, &this_pfn);
167                 if (ret)
168                         break;
169
170                 if (pages_done == 0)
171                         mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
172                 else if (this_pfn != (prev_pfn + 1))
173                         ret = -EFAULT;
174
175                 if (ret)
176                         break;
177
178                 prev_pfn = this_pfn;
179                 user_address += PAGE_SIZE;
180                 pages_done++;
181         }
182
183         if (!ret)
184                 mem->is_userptr = 1;
185
186  out_up:
187         up_read(&current->mm->mmap_sem);
188
189         return ret;
190 }
191
192 static void *__videobuf_alloc(size_t size)
193 {
194         struct videobuf_dma_contig_memory *mem;
195         struct videobuf_buffer *vb;
196
197         vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
198         if (vb) {
199                 mem = vb->priv = ((char *)vb) + size;
200                 mem->magic = MAGIC_DC_MEM;
201         }
202
203         return vb;
204 }
205
206 static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf)
207 {
208         struct videobuf_dma_contig_memory *mem = buf->priv;
209
210         BUG_ON(!mem);
211         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
212
213         return mem->vaddr;
214 }
215
216 static int __videobuf_iolock(struct videobuf_queue *q,
217                              struct videobuf_buffer *vb,
218                              struct v4l2_framebuffer *fbuf)
219 {
220         struct videobuf_dma_contig_memory *mem = vb->priv;
221
222         BUG_ON(!mem);
223         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
224
225         switch (vb->memory) {
226         case V4L2_MEMORY_MMAP:
227                 dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
228
229                 /* All handling should be done by __videobuf_mmap_mapper() */
230                 if (!mem->vaddr) {
231                         dev_err(q->dev, "memory is not alloced/mmapped.\n");
232                         return -EINVAL;
233                 }
234                 break;
235         case V4L2_MEMORY_USERPTR:
236                 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
237
238                 /* handle pointer from user space */
239                 if (vb->baddr)
240                         return videobuf_dma_contig_user_get(mem, vb);
241
242                 /* allocate memory for the read() method */
243                 mem->size = PAGE_ALIGN(vb->size);
244                 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
245                                                 &mem->dma_handle, GFP_KERNEL);
246                 if (!mem->vaddr) {
247                         dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
248                                          mem->size);
249                         return -ENOMEM;
250                 }
251
252                 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
253                         mem->vaddr, mem->size);
254                 break;
255         case V4L2_MEMORY_OVERLAY:
256         default:
257                 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
258                         __func__);
259                 return -EINVAL;
260         }
261
262         return 0;
263 }
264
265 static int __videobuf_mmap_free(struct videobuf_queue *q)
266 {
267         unsigned int i;
268
269         dev_dbg(q->dev, "%s\n", __func__);
270         for (i = 0; i < VIDEO_MAX_FRAME; i++) {
271                 if (q->bufs[i] && q->bufs[i]->map)
272                         return -EBUSY;
273         }
274
275         return 0;
276 }
277
278 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
279                                   struct vm_area_struct *vma)
280 {
281         struct videobuf_dma_contig_memory *mem;
282         struct videobuf_mapping *map;
283         unsigned int first;
284         int retval;
285         unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
286
287         dev_dbg(q->dev, "%s\n", __func__);
288         if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
289                 return -EINVAL;
290
291         /* look for first buffer to map */
292         for (first = 0; first < VIDEO_MAX_FRAME; first++) {
293                 if (!q->bufs[first])
294                         continue;
295
296                 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
297                         continue;
298                 if (q->bufs[first]->boff == offset)
299                         break;
300         }
301         if (VIDEO_MAX_FRAME == first) {
302                 dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
303                         offset);
304                 return -EINVAL;
305         }
306
307         /* create mapping + update buffer list */
308         map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
309         if (!map)
310                 return -ENOMEM;
311
312         q->bufs[first]->map = map;
313         map->start = vma->vm_start;
314         map->end = vma->vm_end;
315         map->q = q;
316
317         q->bufs[first]->baddr = vma->vm_start;
318
319         mem = q->bufs[first]->priv;
320         BUG_ON(!mem);
321         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
322
323         mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
324         mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
325                                         &mem->dma_handle, GFP_KERNEL);
326         if (!mem->vaddr) {
327                 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
328                         mem->size);
329                 goto error;
330         }
331         dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
332                 mem->vaddr, mem->size);
333
334         /* Try to remap memory */
335
336         size = vma->vm_end - vma->vm_start;
337         size = (size < mem->size) ? size : mem->size;
338
339         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
340         retval = remap_pfn_range(vma, vma->vm_start,
341                                  mem->dma_handle >> PAGE_SHIFT,
342                                  size, vma->vm_page_prot);
343         if (retval) {
344                 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
345                 dma_free_coherent(q->dev, mem->size,
346                                   mem->vaddr, mem->dma_handle);
347                 goto error;
348         }
349
350         vma->vm_ops          = &videobuf_vm_ops;
351         vma->vm_flags       |= VM_DONTEXPAND;
352         vma->vm_private_data = map;
353
354         dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
355                 map, q, vma->vm_start, vma->vm_end,
356                 (long int) q->bufs[first]->bsize,
357                 vma->vm_pgoff, first);
358
359         videobuf_vm_open(vma);
360
361         return 0;
362
363 error:
364         kfree(map);
365         return -ENOMEM;
366 }
367
368 static int __videobuf_copy_to_user(struct videobuf_queue *q,
369                                    char __user *data, size_t count,
370                                    int nonblocking)
371 {
372         struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
373         void *vaddr;
374
375         BUG_ON(!mem);
376         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
377         BUG_ON(!mem->vaddr);
378
379         /* copy to userspace */
380         if (count > q->read_buf->size - q->read_off)
381                 count = q->read_buf->size - q->read_off;
382
383         vaddr = mem->vaddr;
384
385         if (copy_to_user(data, vaddr + q->read_off, count))
386                 return -EFAULT;
387
388         return count;
389 }
390
391 static int __videobuf_copy_stream(struct videobuf_queue *q,
392                                   char __user *data, size_t count, size_t pos,
393                                   int vbihack, int nonblocking)
394 {
395         unsigned int  *fc;
396         struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
397
398         BUG_ON(!mem);
399         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
400
401         if (vbihack) {
402                 /* dirty, undocumented hack -- pass the frame counter
403                         * within the last four bytes of each vbi data block.
404                         * We need that one to maintain backward compatibility
405                         * to all vbi decoding software out there ... */
406                 fc = (unsigned int *)mem->vaddr;
407                 fc += (q->read_buf->size >> 2) - 1;
408                 *fc = q->read_buf->field_count >> 1;
409                 dev_dbg(q->dev, "vbihack: %d\n", *fc);
410         }
411
412         /* copy stuff using the common method */
413         count = __videobuf_copy_to_user(q, data, count, nonblocking);
414
415         if ((count == -EFAULT) && (pos == 0))
416                 return -EFAULT;
417
418         return count;
419 }
420
421 static struct videobuf_qtype_ops qops = {
422         .magic        = MAGIC_QTYPE_OPS,
423
424         .alloc        = __videobuf_alloc,
425         .iolock       = __videobuf_iolock,
426         .mmap_free    = __videobuf_mmap_free,
427         .mmap_mapper  = __videobuf_mmap_mapper,
428         .video_copy_to_user = __videobuf_copy_to_user,
429         .copy_stream  = __videobuf_copy_stream,
430         .vmalloc      = __videobuf_to_vmalloc,
431 };
432
433 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
434                                     const struct videobuf_queue_ops *ops,
435                                     struct device *dev,
436                                     spinlock_t *irqlock,
437                                     enum v4l2_buf_type type,
438                                     enum v4l2_field field,
439                                     unsigned int msize,
440                                     void *priv)
441 {
442         videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
443                                  priv, &qops);
444 }
445 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
446
447 dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
448 {
449         struct videobuf_dma_contig_memory *mem = buf->priv;
450
451         BUG_ON(!mem);
452         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
453
454         return mem->dma_handle;
455 }
456 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
457
458 void videobuf_dma_contig_free(struct videobuf_queue *q,
459                               struct videobuf_buffer *buf)
460 {
461         struct videobuf_dma_contig_memory *mem = buf->priv;
462
463         /* mmapped memory can't be freed here, otherwise mmapped region
464            would be released, while still needed. In this case, the memory
465            release should happen inside videobuf_vm_close().
466            So, it should free memory only if the memory were allocated for
467            read() operation.
468          */
469         if (buf->memory != V4L2_MEMORY_USERPTR)
470                 return;
471
472         if (!mem)
473                 return;
474
475         MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
476
477         /* handle user space pointer case */
478         if (buf->baddr) {
479                 videobuf_dma_contig_user_put(mem);
480                 return;
481         }
482
483         /* read() method */
484         dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
485         mem->vaddr = NULL;
486 }
487 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
488
489 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
490 MODULE_AUTHOR("Magnus Damm");
491 MODULE_LICENSE("GPL");