]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/drm_gem_vram_helper.c
drm/vram: Unexport internal functions of VRAM MM
[linux.git] / drivers / gpu / drm / drm_gem_vram_helper.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <drm/drm_debugfs.h>
4 #include <drm/drm_device.h>
5 #include <drm/drm_file.h>
6 #include <drm/drm_gem_ttm_helper.h>
7 #include <drm/drm_gem_vram_helper.h>
8 #include <drm/drm_mode.h>
9 #include <drm/drm_prime.h>
10 #include <drm/ttm/ttm_page_alloc.h>
11
12 static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
13
14 /**
15  * DOC: overview
16  *
17  * This library provides a GEM buffer object that is backed by video RAM
18  * (VRAM). It can be used for framebuffer devices with dedicated memory.
19  *
20  * The data structure &struct drm_vram_mm and its helpers implement a memory
21  * manager for simple framebuffer devices with dedicated video memory. Buffer
22  * objects are either placed in video RAM or evicted to system memory. The rsp.
23  * buffer object is provided by &struct drm_gem_vram_object.
24  */
25
26 /*
27  * Buffer-objects helpers
28  */
29
30 static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
31 {
32         /* We got here via ttm_bo_put(), which means that the
33          * TTM buffer object in 'bo' has already been cleaned
34          * up; only release the GEM object.
35          */
36
37         WARN_ON(gbo->kmap_use_count);
38         WARN_ON(gbo->kmap.virtual);
39
40         drm_gem_object_release(&gbo->bo.base);
41 }
42
43 static void drm_gem_vram_destroy(struct drm_gem_vram_object *gbo)
44 {
45         drm_gem_vram_cleanup(gbo);
46         kfree(gbo);
47 }
48
49 static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
50 {
51         struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
52
53         drm_gem_vram_destroy(gbo);
54 }
55
56 static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
57                                    unsigned long pl_flag)
58 {
59         unsigned int i;
60         unsigned int c = 0;
61
62         gbo->placement.placement = gbo->placements;
63         gbo->placement.busy_placement = gbo->placements;
64
65         if (pl_flag & TTM_PL_FLAG_VRAM)
66                 gbo->placements[c++].flags = TTM_PL_FLAG_WC |
67                                              TTM_PL_FLAG_UNCACHED |
68                                              TTM_PL_FLAG_VRAM;
69
70         if (pl_flag & TTM_PL_FLAG_SYSTEM)
71                 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
72                                              TTM_PL_FLAG_SYSTEM;
73
74         if (!c)
75                 gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
76                                              TTM_PL_FLAG_SYSTEM;
77
78         gbo->placement.num_placement = c;
79         gbo->placement.num_busy_placement = c;
80
81         for (i = 0; i < c; ++i) {
82                 gbo->placements[i].fpfn = 0;
83                 gbo->placements[i].lpfn = 0;
84         }
85 }
86
87 static int drm_gem_vram_init(struct drm_device *dev,
88                              struct ttm_bo_device *bdev,
89                              struct drm_gem_vram_object *gbo,
90                              size_t size, unsigned long pg_align,
91                              bool interruptible)
92 {
93         int ret;
94         size_t acc_size;
95
96         if (!gbo->bo.base.funcs)
97                 gbo->bo.base.funcs = &drm_gem_vram_object_funcs;
98
99         ret = drm_gem_object_init(dev, &gbo->bo.base, size);
100         if (ret)
101                 return ret;
102
103         acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
104
105         gbo->bo.bdev = bdev;
106         drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
107
108         ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
109                           &gbo->placement, pg_align, interruptible, acc_size,
110                           NULL, NULL, ttm_buffer_object_destroy);
111         if (ret)
112                 goto err_drm_gem_object_release;
113
114         return 0;
115
116 err_drm_gem_object_release:
117         drm_gem_object_release(&gbo->bo.base);
118         return ret;
119 }
120
121 /**
122  * drm_gem_vram_create() - Creates a VRAM-backed GEM object
123  * @dev:                the DRM device
124  * @bdev:               the TTM BO device backing the object
125  * @size:               the buffer size in bytes
126  * @pg_align:           the buffer's alignment in multiples of the page size
127  * @interruptible:      sleep interruptible if waiting for memory
128  *
129  * Returns:
130  * A new instance of &struct drm_gem_vram_object on success, or
131  * an ERR_PTR()-encoded error code otherwise.
132  */
133 struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
134                                                 struct ttm_bo_device *bdev,
135                                                 size_t size,
136                                                 unsigned long pg_align,
137                                                 bool interruptible)
138 {
139         struct drm_gem_vram_object *gbo;
140         int ret;
141
142         gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
143         if (!gbo)
144                 return ERR_PTR(-ENOMEM);
145
146         ret = drm_gem_vram_init(dev, bdev, gbo, size, pg_align, interruptible);
147         if (ret < 0)
148                 goto err_kfree;
149
150         return gbo;
151
152 err_kfree:
153         kfree(gbo);
154         return ERR_PTR(ret);
155 }
156 EXPORT_SYMBOL(drm_gem_vram_create);
157
158 /**
159  * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
160  * @gbo:        the GEM VRAM object
161  *
162  * See ttm_bo_put() for more information.
163  */
164 void drm_gem_vram_put(struct drm_gem_vram_object *gbo)
165 {
166         ttm_bo_put(&gbo->bo);
167 }
168 EXPORT_SYMBOL(drm_gem_vram_put);
169
170 /**
171  * drm_gem_vram_mmap_offset() - Returns a GEM VRAM object's mmap offset
172  * @gbo:        the GEM VRAM object
173  *
174  * See drm_vma_node_offset_addr() for more information.
175  *
176  * Returns:
177  * The buffer object's offset for userspace mappings on success, or
178  * 0 if no offset is allocated.
179  */
180 u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo)
181 {
182         return drm_vma_node_offset_addr(&gbo->bo.base.vma_node);
183 }
184 EXPORT_SYMBOL(drm_gem_vram_mmap_offset);
185
186 /**
187  * drm_gem_vram_offset() - \
188         Returns a GEM VRAM object's offset in video memory
189  * @gbo:        the GEM VRAM object
190  *
191  * This function returns the buffer object's offset in the device's video
192  * memory. The buffer object has to be pinned to %TTM_PL_VRAM.
193  *
194  * Returns:
195  * The buffer object's offset in video memory on success, or
196  * a negative errno code otherwise.
197  */
198 s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
199 {
200         if (WARN_ON_ONCE(!gbo->pin_count))
201                 return (s64)-ENODEV;
202         return gbo->bo.offset;
203 }
204 EXPORT_SYMBOL(drm_gem_vram_offset);
205
206 static int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
207                                    unsigned long pl_flag)
208 {
209         int i, ret;
210         struct ttm_operation_ctx ctx = { false, false };
211
212         if (gbo->pin_count)
213                 goto out;
214
215         if (pl_flag)
216                 drm_gem_vram_placement(gbo, pl_flag);
217
218         for (i = 0; i < gbo->placement.num_placement; ++i)
219                 gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
220
221         ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
222         if (ret < 0)
223                 return ret;
224
225 out:
226         ++gbo->pin_count;
227
228         return 0;
229 }
230
231 /**
232  * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
233  * @gbo:        the GEM VRAM object
234  * @pl_flag:    a bitmask of possible memory regions
235  *
236  * Pinning a buffer object ensures that it is not evicted from
237  * a memory region. A pinned buffer object has to be unpinned before
238  * it can be pinned to another region. If the pl_flag argument is 0,
239  * the buffer is pinned at its current location (video RAM or system
240  * memory).
241  *
242  * Returns:
243  * 0 on success, or
244  * a negative error code otherwise.
245  */
246 int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
247 {
248         int ret;
249
250         ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
251         if (ret)
252                 return ret;
253         ret = drm_gem_vram_pin_locked(gbo, pl_flag);
254         ttm_bo_unreserve(&gbo->bo);
255
256         return ret;
257 }
258 EXPORT_SYMBOL(drm_gem_vram_pin);
259
260 static int drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo)
261 {
262         int i, ret;
263         struct ttm_operation_ctx ctx = { false, false };
264
265         if (WARN_ON_ONCE(!gbo->pin_count))
266                 return 0;
267
268         --gbo->pin_count;
269         if (gbo->pin_count)
270                 return 0;
271
272         for (i = 0; i < gbo->placement.num_placement ; ++i)
273                 gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
274
275         ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
276         if (ret < 0)
277                 return ret;
278
279         return 0;
280 }
281
282 /**
283  * drm_gem_vram_unpin() - Unpins a GEM VRAM object
284  * @gbo:        the GEM VRAM object
285  *
286  * Returns:
287  * 0 on success, or
288  * a negative error code otherwise.
289  */
290 int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
291 {
292         int ret;
293
294         ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
295         if (ret)
296                 return ret;
297         ret = drm_gem_vram_unpin_locked(gbo);
298         ttm_bo_unreserve(&gbo->bo);
299
300         return ret;
301 }
302 EXPORT_SYMBOL(drm_gem_vram_unpin);
303
304 static void *drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
305                                       bool map, bool *is_iomem)
306 {
307         int ret;
308         struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
309
310         if (gbo->kmap_use_count > 0)
311                 goto out;
312
313         if (kmap->virtual || !map)
314                 goto out;
315
316         ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, kmap);
317         if (ret)
318                 return ERR_PTR(ret);
319
320 out:
321         if (!kmap->virtual) {
322                 if (is_iomem)
323                         *is_iomem = false;
324                 return NULL; /* not mapped; don't increment ref */
325         }
326         ++gbo->kmap_use_count;
327         if (is_iomem)
328                 return ttm_kmap_obj_virtual(kmap, is_iomem);
329         return kmap->virtual;
330 }
331
332 /**
333  * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
334  * @gbo:        the GEM VRAM object
335  * @map:        establish a mapping if necessary
336  * @is_iomem:   returns true if the mapped memory is I/O memory, or false \
337         otherwise; can be NULL
338  *
339  * This function maps the buffer object into the kernel's address space
340  * or returns the current mapping. If the parameter map is false, the
341  * function only queries the current mapping, but does not establish a
342  * new one.
343  *
344  * Returns:
345  * The buffers virtual address if mapped, or
346  * NULL if not mapped, or
347  * an ERR_PTR()-encoded error code otherwise.
348  */
349 void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
350                         bool *is_iomem)
351 {
352         int ret;
353         void *virtual;
354
355         ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
356         if (ret)
357                 return ERR_PTR(ret);
358         virtual = drm_gem_vram_kmap_locked(gbo, map, is_iomem);
359         ttm_bo_unreserve(&gbo->bo);
360
361         return virtual;
362 }
363 EXPORT_SYMBOL(drm_gem_vram_kmap);
364
365 static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
366 {
367         if (WARN_ON_ONCE(!gbo->kmap_use_count))
368                 return;
369         if (--gbo->kmap_use_count > 0)
370                 return;
371
372         /*
373          * Permanently mapping and unmapping buffers adds overhead from
374          * updating the page tables and creates debugging output. Therefore,
375          * we delay the actual unmap operation until the BO gets evicted
376          * from memory. See drm_gem_vram_bo_driver_move_notify().
377          */
378 }
379
380 /**
381  * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
382  * @gbo:        the GEM VRAM object
383  */
384 void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
385 {
386         int ret;
387
388         ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
389         if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
390                 return;
391         drm_gem_vram_kunmap_locked(gbo);
392         ttm_bo_unreserve(&gbo->bo);
393 }
394 EXPORT_SYMBOL(drm_gem_vram_kunmap);
395
396 /**
397  * drm_gem_vram_fill_create_dumb() - \
398         Helper for implementing &struct drm_driver.dumb_create
399  * @file:               the DRM file
400  * @dev:                the DRM device
401  * @bdev:               the TTM BO device managing the buffer object
402  * @pg_align:           the buffer's alignment in multiples of the page size
403  * @interruptible:      sleep interruptible if waiting for memory
404  * @args:               the arguments as provided to \
405                                 &struct drm_driver.dumb_create
406  *
407  * This helper function fills &struct drm_mode_create_dumb, which is used
408  * by &struct drm_driver.dumb_create. Implementations of this interface
409  * should forwards their arguments to this helper, plus the driver-specific
410  * parameters.
411  *
412  * Returns:
413  * 0 on success, or
414  * a negative error code otherwise.
415  */
416 int drm_gem_vram_fill_create_dumb(struct drm_file *file,
417                                   struct drm_device *dev,
418                                   struct ttm_bo_device *bdev,
419                                   unsigned long pg_align,
420                                   bool interruptible,
421                                   struct drm_mode_create_dumb *args)
422 {
423         size_t pitch, size;
424         struct drm_gem_vram_object *gbo;
425         int ret;
426         u32 handle;
427
428         pitch = args->width * ((args->bpp + 7) / 8);
429         size = pitch * args->height;
430
431         size = roundup(size, PAGE_SIZE);
432         if (!size)
433                 return -EINVAL;
434
435         gbo = drm_gem_vram_create(dev, bdev, size, pg_align, interruptible);
436         if (IS_ERR(gbo))
437                 return PTR_ERR(gbo);
438
439         ret = drm_gem_handle_create(file, &gbo->bo.base, &handle);
440         if (ret)
441                 goto err_drm_gem_object_put_unlocked;
442
443         drm_gem_object_put_unlocked(&gbo->bo.base);
444
445         args->pitch = pitch;
446         args->size = size;
447         args->handle = handle;
448
449         return 0;
450
451 err_drm_gem_object_put_unlocked:
452         drm_gem_object_put_unlocked(&gbo->bo.base);
453         return ret;
454 }
455 EXPORT_SYMBOL(drm_gem_vram_fill_create_dumb);
456
457 /*
458  * Helpers for struct ttm_bo_driver
459  */
460
461 static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
462 {
463         return (bo->destroy == ttm_buffer_object_destroy);
464 }
465
466 static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo,
467                                                struct ttm_placement *pl)
468 {
469         drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
470         *pl = gbo->placement;
471 }
472
473 static int drm_gem_vram_bo_driver_verify_access(struct drm_gem_vram_object *gbo,
474                                                 struct file *filp)
475 {
476         return drm_vma_node_verify_access(&gbo->bo.base.vma_node,
477                                           filp->private_data);
478 }
479
480 static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
481                                                bool evict,
482                                                struct ttm_mem_reg *new_mem)
483 {
484         struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
485
486         if (WARN_ON_ONCE(gbo->kmap_use_count))
487                 return;
488
489         if (!kmap->virtual)
490                 return;
491         ttm_bo_kunmap(kmap);
492         kmap->virtual = NULL;
493 }
494
495 /*
496  * Helpers for struct drm_gem_object_funcs
497  */
498
499 /**
500  * drm_gem_vram_object_free() - \
501         Implements &struct drm_gem_object_funcs.free
502  * @gem:       GEM object. Refers to &struct drm_gem_vram_object.gem
503  */
504 static void drm_gem_vram_object_free(struct drm_gem_object *gem)
505 {
506         struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
507
508         drm_gem_vram_put(gbo);
509 }
510
511 /*
512  * Helpers for dump buffers
513  */
514
515 /**
516  * drm_gem_vram_driver_create_dumb() - \
517         Implements &struct drm_driver.dumb_create
518  * @file:               the DRM file
519  * @dev:                the DRM device
520  * @args:               the arguments as provided to \
521                                 &struct drm_driver.dumb_create
522  *
523  * This function requires the driver to use @drm_device.vram_mm for its
524  * instance of VRAM MM.
525  *
526  * Returns:
527  * 0 on success, or
528  * a negative error code otherwise.
529  */
530 int drm_gem_vram_driver_dumb_create(struct drm_file *file,
531                                     struct drm_device *dev,
532                                     struct drm_mode_create_dumb *args)
533 {
534         if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
535                 return -EINVAL;
536
537         return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, 0,
538                                              false, args);
539 }
540 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
541
542 /**
543  * drm_gem_vram_driver_dumb_mmap_offset() - \
544         Implements &struct drm_driver.dumb_mmap_offset
545  * @file:       DRM file pointer.
546  * @dev:        DRM device.
547  * @handle:     GEM handle
548  * @offset:     Returns the mapping's memory offset on success
549  *
550  * Returns:
551  * 0 on success, or
552  * a negative errno code otherwise.
553  */
554 int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
555                                          struct drm_device *dev,
556                                          uint32_t handle, uint64_t *offset)
557 {
558         struct drm_gem_object *gem;
559         struct drm_gem_vram_object *gbo;
560
561         gem = drm_gem_object_lookup(file, handle);
562         if (!gem)
563                 return -ENOENT;
564
565         gbo = drm_gem_vram_of_gem(gem);
566         *offset = drm_gem_vram_mmap_offset(gbo);
567
568         drm_gem_object_put_unlocked(gem);
569
570         return 0;
571 }
572 EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
573
574 /*
575  * PRIME helpers
576  */
577
578 /**
579  * drm_gem_vram_object_pin() - \
580         Implements &struct drm_gem_object_funcs.pin
581  * @gem:        The GEM object to pin
582  *
583  * Returns:
584  * 0 on success, or
585  * a negative errno code otherwise.
586  */
587 static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
588 {
589         struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
590
591         /* Fbdev console emulation is the use case of these PRIME
592          * helpers. This may involve updating a hardware buffer from
593          * a shadow FB. We pin the buffer to it's current location
594          * (either video RAM or system memory) to prevent it from
595          * being relocated during the update operation. If you require
596          * the buffer to be pinned to VRAM, implement a callback that
597          * sets the flags accordingly.
598          */
599         return drm_gem_vram_pin(gbo, 0);
600 }
601
602 /**
603  * drm_gem_vram_object_unpin() - \
604         Implements &struct drm_gem_object_funcs.unpin
605  * @gem:        The GEM object to unpin
606  */
607 static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
608 {
609         struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
610
611         drm_gem_vram_unpin(gbo);
612 }
613
614 /**
615  * drm_gem_vram_object_vmap() - \
616         Implements &struct drm_gem_object_funcs.vmap
617  * @gem:        The GEM object to map
618  *
619  * Returns:
620  * The buffers virtual address on success, or
621  * NULL otherwise.
622  */
623 static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem)
624 {
625         struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
626         int ret;
627         void *base;
628
629         ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
630         if (ret)
631                 return ERR_PTR(ret);
632
633         ret = drm_gem_vram_pin_locked(gbo, 0);
634         if (ret)
635                 goto err_ttm_bo_unreserve;
636         base = drm_gem_vram_kmap_locked(gbo, true, NULL);
637         if (IS_ERR(base)) {
638                 ret = PTR_ERR(base);
639                 goto err_drm_gem_vram_unpin_locked;
640         }
641
642         ttm_bo_unreserve(&gbo->bo);
643
644         return base;
645
646 err_drm_gem_vram_unpin_locked:
647         drm_gem_vram_unpin_locked(gbo);
648 err_ttm_bo_unreserve:
649         ttm_bo_unreserve(&gbo->bo);
650         return ERR_PTR(ret);
651 }
652
653 /**
654  * drm_gem_vram_object_vunmap() - \
655         Implements &struct drm_gem_object_funcs.vunmap
656  * @gem:        The GEM object to unmap
657  * @vaddr:      The mapping's base address
658  */
659 static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
660                                        void *vaddr)
661 {
662         struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
663         int ret;
664
665         ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
666         if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
667                 return;
668
669         drm_gem_vram_kunmap_locked(gbo);
670         drm_gem_vram_unpin_locked(gbo);
671
672         ttm_bo_unreserve(&gbo->bo);
673 }
674
675 /*
676  * GEM object funcs
677  */
678
679 static const struct drm_gem_object_funcs drm_gem_vram_object_funcs = {
680         .free   = drm_gem_vram_object_free,
681         .pin    = drm_gem_vram_object_pin,
682         .unpin  = drm_gem_vram_object_unpin,
683         .vmap   = drm_gem_vram_object_vmap,
684         .vunmap = drm_gem_vram_object_vunmap,
685         .print_info = drm_gem_ttm_print_info,
686 };
687
688 /*
689  * VRAM memory manager
690  */
691
692 /*
693  * TTM TT
694  */
695
696 static void backend_func_destroy(struct ttm_tt *tt)
697 {
698         ttm_tt_fini(tt);
699         kfree(tt);
700 }
701
702 static struct ttm_backend_func backend_func = {
703         .destroy = backend_func_destroy
704 };
705
706 /*
707  * TTM BO device
708  */
709
710 static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
711                                               uint32_t page_flags)
712 {
713         struct ttm_tt *tt;
714         int ret;
715
716         tt = kzalloc(sizeof(*tt), GFP_KERNEL);
717         if (!tt)
718                 return NULL;
719
720         tt->func = &backend_func;
721
722         ret = ttm_tt_init(tt, bo, page_flags);
723         if (ret < 0)
724                 goto err_ttm_tt_init;
725
726         return tt;
727
728 err_ttm_tt_init:
729         kfree(tt);
730         return NULL;
731 }
732
733 static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
734                                    struct ttm_mem_type_manager *man)
735 {
736         switch (type) {
737         case TTM_PL_SYSTEM:
738                 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
739                 man->available_caching = TTM_PL_MASK_CACHING;
740                 man->default_caching = TTM_PL_FLAG_CACHED;
741                 break;
742         case TTM_PL_VRAM:
743                 man->func = &ttm_bo_manager_func;
744                 man->flags = TTM_MEMTYPE_FLAG_FIXED |
745                              TTM_MEMTYPE_FLAG_MAPPABLE;
746                 man->available_caching = TTM_PL_FLAG_UNCACHED |
747                                          TTM_PL_FLAG_WC;
748                 man->default_caching = TTM_PL_FLAG_WC;
749                 break;
750         default:
751                 return -EINVAL;
752         }
753         return 0;
754 }
755
756 static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
757                                   struct ttm_placement *placement)
758 {
759         struct drm_gem_vram_object *gbo;
760
761         /* TTM may pass BOs that are not GEM VRAM BOs. */
762         if (!drm_is_gem_vram(bo))
763                 return;
764
765         gbo = drm_gem_vram_of_bo(bo);
766
767         drm_gem_vram_bo_driver_evict_flags(gbo, placement);
768 }
769
770 static int bo_driver_verify_access(struct ttm_buffer_object *bo,
771                                    struct file *filp)
772 {
773         struct drm_gem_vram_object *gbo;
774
775         /* TTM may pass BOs that are not GEM VRAM BOs. */
776         if (!drm_is_gem_vram(bo))
777                 return -EINVAL;
778
779         gbo = drm_gem_vram_of_bo(bo);
780
781         return drm_gem_vram_bo_driver_verify_access(gbo, filp);
782 }
783
784 static void bo_driver_move_notify(struct ttm_buffer_object *bo,
785                                   bool evict,
786                                   struct ttm_mem_reg *new_mem)
787 {
788         struct drm_gem_vram_object *gbo;
789
790         /* TTM may pass BOs that are not GEM VRAM BOs. */
791         if (!drm_is_gem_vram(bo))
792                 return;
793
794         gbo = drm_gem_vram_of_bo(bo);
795
796         drm_gem_vram_bo_driver_move_notify(gbo, evict, new_mem);
797 }
798
799 static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
800                                     struct ttm_mem_reg *mem)
801 {
802         struct ttm_mem_type_manager *man = bdev->man + mem->mem_type;
803         struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
804
805         if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
806                 return -EINVAL;
807
808         mem->bus.addr = NULL;
809         mem->bus.size = mem->num_pages << PAGE_SHIFT;
810
811         switch (mem->mem_type) {
812         case TTM_PL_SYSTEM:     /* nothing to do */
813                 mem->bus.offset = 0;
814                 mem->bus.base = 0;
815                 mem->bus.is_iomem = false;
816                 break;
817         case TTM_PL_VRAM:
818                 mem->bus.offset = mem->start << PAGE_SHIFT;
819                 mem->bus.base = vmm->vram_base;
820                 mem->bus.is_iomem = true;
821                 break;
822         default:
823                 return -EINVAL;
824         }
825
826         return 0;
827 }
828
829 static void bo_driver_io_mem_free(struct ttm_bo_device *bdev,
830                                   struct ttm_mem_reg *mem)
831 { }
832
833 static struct ttm_bo_driver bo_driver = {
834         .ttm_tt_create = bo_driver_ttm_tt_create,
835         .ttm_tt_populate = ttm_pool_populate,
836         .ttm_tt_unpopulate = ttm_pool_unpopulate,
837         .init_mem_type = bo_driver_init_mem_type,
838         .eviction_valuable = ttm_bo_eviction_valuable,
839         .evict_flags = bo_driver_evict_flags,
840         .verify_access = bo_driver_verify_access,
841         .move_notify = bo_driver_move_notify,
842         .io_mem_reserve = bo_driver_io_mem_reserve,
843         .io_mem_free = bo_driver_io_mem_free,
844 };
845
846 /*
847  * struct drm_vram_mm
848  */
849
850 #if defined(CONFIG_DEBUG_FS)
851 static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
852 {
853         struct drm_info_node *node = (struct drm_info_node *) m->private;
854         struct drm_vram_mm *vmm = node->minor->dev->vram_mm;
855         struct drm_mm *mm = vmm->bdev.man[TTM_PL_VRAM].priv;
856         struct ttm_bo_global *glob = vmm->bdev.glob;
857         struct drm_printer p = drm_seq_file_printer(m);
858
859         spin_lock(&glob->lru_lock);
860         drm_mm_print(mm, &p);
861         spin_unlock(&glob->lru_lock);
862         return 0;
863 }
864
865 static const struct drm_info_list drm_vram_mm_debugfs_list[] = {
866         { "vram-mm", drm_vram_mm_debugfs, 0, NULL },
867 };
868 #endif
869
870 /**
871  * drm_vram_mm_debugfs_init() - Register VRAM MM debugfs file.
872  *
873  * @minor: drm minor device.
874  *
875  * Returns:
876  * 0 on success, or
877  * a negative error code otherwise.
878  */
879 int drm_vram_mm_debugfs_init(struct drm_minor *minor)
880 {
881         int ret = 0;
882
883 #if defined(CONFIG_DEBUG_FS)
884         ret = drm_debugfs_create_files(drm_vram_mm_debugfs_list,
885                                        ARRAY_SIZE(drm_vram_mm_debugfs_list),
886                                        minor->debugfs_root, minor);
887 #endif
888         return ret;
889 }
890 EXPORT_SYMBOL(drm_vram_mm_debugfs_init);
891
892 static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
893                             uint64_t vram_base, size_t vram_size)
894 {
895         int ret;
896
897         vmm->vram_base = vram_base;
898         vmm->vram_size = vram_size;
899
900         ret = ttm_bo_device_init(&vmm->bdev, &bo_driver,
901                                  dev->anon_inode->i_mapping,
902                                  dev->vma_offset_manager,
903                                  true);
904         if (ret)
905                 return ret;
906
907         ret = ttm_bo_init_mm(&vmm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);
908         if (ret)
909                 return ret;
910
911         return 0;
912 }
913
914 static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
915 {
916         ttm_bo_device_release(&vmm->bdev);
917 }
918
919 static int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma,
920                             struct drm_vram_mm *vmm)
921 {
922         return ttm_bo_mmap(filp, vma, &vmm->bdev);
923 }
924
925 /*
926  * Helpers for integration with struct drm_device
927  */
928
929 /**
930  * drm_vram_helper_alloc_mm - Allocates a device's instance of \
931         &struct drm_vram_mm
932  * @dev:        the DRM device
933  * @vram_base:  the base address of the video memory
934  * @vram_size:  the size of the video memory in bytes
935  *
936  * Returns:
937  * The new instance of &struct drm_vram_mm on success, or
938  * an ERR_PTR()-encoded errno code otherwise.
939  */
940 struct drm_vram_mm *drm_vram_helper_alloc_mm(
941         struct drm_device *dev, uint64_t vram_base, size_t vram_size)
942 {
943         int ret;
944
945         if (WARN_ON(dev->vram_mm))
946                 return dev->vram_mm;
947
948         dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL);
949         if (!dev->vram_mm)
950                 return ERR_PTR(-ENOMEM);
951
952         ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size);
953         if (ret)
954                 goto err_kfree;
955
956         return dev->vram_mm;
957
958 err_kfree:
959         kfree(dev->vram_mm);
960         dev->vram_mm = NULL;
961         return ERR_PTR(ret);
962 }
963 EXPORT_SYMBOL(drm_vram_helper_alloc_mm);
964
965 /**
966  * drm_vram_helper_release_mm - Releases a device's instance of \
967         &struct drm_vram_mm
968  * @dev:        the DRM device
969  */
970 void drm_vram_helper_release_mm(struct drm_device *dev)
971 {
972         if (!dev->vram_mm)
973                 return;
974
975         drm_vram_mm_cleanup(dev->vram_mm);
976         kfree(dev->vram_mm);
977         dev->vram_mm = NULL;
978 }
979 EXPORT_SYMBOL(drm_vram_helper_release_mm);
980
981 /*
982  * Helpers for &struct file_operations
983  */
984
985 /**
986  * drm_vram_mm_file_operations_mmap() - \
987         Implements &struct file_operations.mmap()
988  * @filp:       the mapping's file structure
989  * @vma:        the mapping's memory area
990  *
991  * Returns:
992  * 0 on success, or
993  * a negative error code otherwise.
994  */
995 int drm_vram_mm_file_operations_mmap(
996         struct file *filp, struct vm_area_struct *vma)
997 {
998         struct drm_file *file_priv = filp->private_data;
999         struct drm_device *dev = file_priv->minor->dev;
1000
1001         if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
1002                 return -EINVAL;
1003
1004         return drm_vram_mm_mmap(filp, vma, dev->vram_mm);
1005 }
1006 EXPORT_SYMBOL(drm_vram_mm_file_operations_mmap);