aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2017-01-04 04:12:57 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-01-06 05:04:54 -0500
commit62a0d98a188cc4ebd8ea54b37d274ec20465e464 (patch)
treebb649f5cc408727179380fce600adeba99b2ebbd
parent99c48e1e38f0aeaa107ad67c8d91f6c9d9d567a9 (diff)
drm: allow to use mmuless SoC
Some SoC without MMU have display driver where a drm/kms driver could be implemented. Before doing such kind of thing drm/kms must allow to use mmuless devices. This patch propose to remove MMU configuration flag and add a cma helper function to help implementing mmuless display driver version 4: - add documentation about drm_gem_cma_get_unmapped_area() - stub it MMU case Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> [danvet: Use recommended struct member references in kernel-doc.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1483521177-21794-4-git-send-email-benjamin.gaignard@linaro.org
-rw-r--r--Documentation/gpu/drm-mm.rst11
-rw-r--r--drivers/gpu/drm/Kconfig4
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c71
-rw-r--r--include/drm/drm_gem_cma_helper.h17
4 files changed, 101 insertions, 2 deletions
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index d3c6d77246cd..1ea94fc86caa 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -310,6 +310,17 @@ created.
310Drivers that want to map the GEM object upfront instead of handling page 310Drivers that want to map the GEM object upfront instead of handling page
311faults can implement their own mmap file operation handler. 311faults can implement their own mmap file operation handler.
312 312
313For platforms without MMU the GEM core provides a helper method
314:c:func:`drm_gem_cma_get_unmapped_area`. The mmap() routines will call
315this to get a proposed address for the mapping.
316
317To use :c:func:`drm_gem_cma_get_unmapped_area`, drivers must fill the
318struct :c:type:`struct file_operations <file_operations>` get_unmapped_area
319field with a pointer on :c:func:`drm_gem_cma_get_unmapped_area`.
320
321More detailed information about get_unmapped_area can be found in
322Documentation/nommu-mmap.txt
323
313Memory Coherency 324Memory Coherency
314---------------- 325----------------
315 326
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index d56b85c03b7b..505ca1d262ee 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -6,7 +6,7 @@
6# 6#
7menuconfig DRM 7menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU && HAS_DMA 9 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
10 select HDMI 10 select HDMI
11 select FB_CMDLINE 11 select FB_CMDLINE
12 select I2C 12 select I2C
@@ -113,7 +113,7 @@ config DRM_LOAD_EDID_FIRMWARE
113 113
114config DRM_TTM 114config DRM_TTM
115 tristate 115 tristate
116 depends on DRM 116 depends on DRM && MMU
117 help 117 help
118 GPU memory management subsystem for devices with multiple 118 GPU memory management subsystem for devices with multiple
119 GPU memory types. Will be enabled automatically if a device driver 119 GPU memory types. Will be enabled automatically if a device driver
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index e0806a2ad11c..5cf38a474845 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -358,6 +358,77 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
358} 358}
359EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); 359EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
360 360
361#ifndef CONFIG_MMU
362/**
363 * drm_gem_cma_get_unmapped_area - propose address for mapping in noMMU cases
364 * @filp: file object
365 * @addr: memory address
366 * @len: buffer size
367 * @pgoff: page offset
368 * @flags: memory flags
369 *
370 * This function is used in noMMU platforms to propose address mapping
371 * for a given buffer.
372 * It's intended to be used as a direct handler for the struct
373 * &file_operations.get_unmapped_area operation.
374 *
375 * Returns:
376 * mapping address on success or a negative error code on failure.
377 */
378unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
379 unsigned long addr,
380 unsigned long len,
381 unsigned long pgoff,
382 unsigned long flags)
383{
384 struct drm_gem_cma_object *cma_obj;
385 struct drm_gem_object *obj = NULL;
386 struct drm_file *priv = filp->private_data;
387 struct drm_device *dev = priv->minor->dev;
388 struct drm_vma_offset_node *node;
389
390 if (drm_device_is_unplugged(dev))
391 return -ENODEV;
392
393 drm_vma_offset_lock_lookup(dev->vma_offset_manager);
394 node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
395 pgoff,
396 len >> PAGE_SHIFT);
397 if (likely(node)) {
398 obj = container_of(node, struct drm_gem_object, vma_node);
399 /*
400 * When the object is being freed, after it hits 0-refcnt it
401 * proceeds to tear down the object. In the process it will
402 * attempt to remove the VMA offset and so acquire this
403 * mgr->vm_lock. Therefore if we find an object with a 0-refcnt
404 * that matches our range, we know it is in the process of being
405 * destroyed and will be freed as soon as we release the lock -
406 * so we have to check for the 0-refcnted object and treat it as
407 * invalid.
408 */
409 if (!kref_get_unless_zero(&obj->refcount))
410 obj = NULL;
411 }
412
413 drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
414
415 if (!obj)
416 return -EINVAL;
417
418 if (!drm_vma_node_is_allowed(node, priv)) {
419 drm_gem_object_unreference_unlocked(obj);
420 return -EACCES;
421 }
422
423 cma_obj = to_drm_gem_cma_obj(obj);
424
425 drm_gem_object_unreference_unlocked(obj);
426
427 return cma_obj->vaddr ? (unsigned long)cma_obj->vaddr : -EINVAL;
428}
429EXPORT_SYMBOL_GPL(drm_gem_cma_get_unmapped_area);
430#endif
431
361#ifdef CONFIG_DEBUG_FS 432#ifdef CONFIG_DEBUG_FS
362/** 433/**
363 * drm_gem_cma_describe - describe a CMA GEM object for debugfs 434 * drm_gem_cma_describe - describe a CMA GEM object for debugfs
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index acd6af8a8e67..2abcd5190cc1 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -53,6 +53,23 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
53 53
54extern const struct vm_operations_struct drm_gem_cma_vm_ops; 54extern const struct vm_operations_struct drm_gem_cma_vm_ops;
55 55
56#ifndef CONFIG_MMU
57unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
58 unsigned long addr,
59 unsigned long len,
60 unsigned long pgoff,
61 unsigned long flags);
62#else
63static inline unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
64 unsigned long addr,
65 unsigned long len,
66 unsigned long pgoff,
67 unsigned long flags)
68{
69 return -EINVAL;
70}
71#endif
72
56#ifdef CONFIG_DEBUG_FS 73#ifdef CONFIG_DEBUG_FS
57void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m); 74void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m);
58#endif 75#endif