aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_gem.c
diff options
context:
space:
mode:
authorNoralf Trønnes <noralf@tronnes.org>2018-11-10 09:56:45 -0500
committerNoralf Trønnes <noralf@tronnes.org>2018-11-20 08:56:18 -0500
commitb39b5394fabc79acbaafb26b777fd348c868bf7e (patch)
treef47aa84500faa8c323ac76bf7299e038c5f0e89e /drivers/gpu/drm/drm_gem.c
parent7698799f9554deeb0f3abb22857c3deb41c10db8 (diff)
drm/gem: Add drm_gem_object_funcs
This adds an optional function table on GEM objects. The main benefit is for drivers that support more than one type of memory (shmem,vram,cma) for their buffers depending on the hardware it runs on. With the callbacks attached to the GEM object itself, it is easier to have core helpers for the the various buffer types. The driver only has to make the decision about buffer type on GEM object creation and all other callbacks can be handled by the chosen helper. drm_driver->gem_prime_res_obj has not been added since there's a todo to put a reservation_object into drm_gem_object. v3: Add todo entry v2: Drop drm_gem_object_funcs->prime_mmap in favour of drm_gem_prime_mmap() (Daniel Vetter) v1: - drm_gem_object_funcs.map -> .prime_map let it only do PRIME mmap like the function it superseeds (Daniel Vetter) - Flip around the if ladders and make obj->funcs the first choice highlighting the fact that this the new default way of doing it (Daniel Vetter) Signed-off-by: Noralf Trønnes <noralf@tronnes.org> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Christian König <christian.koenig@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181110145647.17580-4-noralf@tronnes.org
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r--drivers/gpu/drm/drm_gem.c109
1 files changed, 100 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 512078ebd97b..8b55ece97967 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -257,7 +257,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
257 struct drm_gem_object *obj = ptr; 257 struct drm_gem_object *obj = ptr;
258 struct drm_device *dev = obj->dev; 258 struct drm_device *dev = obj->dev;
259 259
260 if (dev->driver->gem_close_object) 260 if (obj->funcs && obj->funcs->close)
261 obj->funcs->close(obj, file_priv);
262 else if (dev->driver->gem_close_object)
261 dev->driver->gem_close_object(obj, file_priv); 263 dev->driver->gem_close_object(obj, file_priv);
262 264
263 if (drm_core_check_feature(dev, DRIVER_PRIME)) 265 if (drm_core_check_feature(dev, DRIVER_PRIME))
@@ -410,7 +412,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
410 if (ret) 412 if (ret)
411 goto err_remove; 413 goto err_remove;
412 414
413 if (dev->driver->gem_open_object) { 415 if (obj->funcs && obj->funcs->open) {
416 ret = obj->funcs->open(obj, file_priv);
417 if (ret)
418 goto err_revoke;
419 } else if (dev->driver->gem_open_object) {
414 ret = dev->driver->gem_open_object(obj, file_priv); 420 ret = dev->driver->gem_open_object(obj, file_priv);
415 if (ret) 421 if (ret)
416 goto err_revoke; 422 goto err_revoke;
@@ -835,7 +841,9 @@ drm_gem_object_free(struct kref *kref)
835 container_of(kref, struct drm_gem_object, refcount); 841 container_of(kref, struct drm_gem_object, refcount);
836 struct drm_device *dev = obj->dev; 842 struct drm_device *dev = obj->dev;
837 843
838 if (dev->driver->gem_free_object_unlocked) { 844 if (obj->funcs) {
845 obj->funcs->free(obj);
846 } else if (dev->driver->gem_free_object_unlocked) {
839 dev->driver->gem_free_object_unlocked(obj); 847 dev->driver->gem_free_object_unlocked(obj);
840 } else if (dev->driver->gem_free_object) { 848 } else if (dev->driver->gem_free_object) {
841 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 849 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -864,13 +872,13 @@ drm_gem_object_put_unlocked(struct drm_gem_object *obj)
864 872
865 dev = obj->dev; 873 dev = obj->dev;
866 874
867 if (dev->driver->gem_free_object_unlocked) { 875 if (dev->driver->gem_free_object) {
868 kref_put(&obj->refcount, drm_gem_object_free);
869 } else {
870 might_lock(&dev->struct_mutex); 876 might_lock(&dev->struct_mutex);
871 if (kref_put_mutex(&obj->refcount, drm_gem_object_free, 877 if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
872 &dev->struct_mutex)) 878 &dev->struct_mutex))
873 mutex_unlock(&dev->struct_mutex); 879 mutex_unlock(&dev->struct_mutex);
880 } else {
881 kref_put(&obj->refcount, drm_gem_object_free);
874 } 882 }
875} 883}
876EXPORT_SYMBOL(drm_gem_object_put_unlocked); 884EXPORT_SYMBOL(drm_gem_object_put_unlocked);
@@ -960,11 +968,14 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
960 if (obj_size < vma->vm_end - vma->vm_start) 968 if (obj_size < vma->vm_end - vma->vm_start)
961 return -EINVAL; 969 return -EINVAL;
962 970
963 if (!dev->driver->gem_vm_ops) 971 if (obj->funcs && obj->funcs->vm_ops)
972 vma->vm_ops = obj->funcs->vm_ops;
973 else if (dev->driver->gem_vm_ops)
974 vma->vm_ops = dev->driver->gem_vm_ops;
975 else
964 return -EINVAL; 976 return -EINVAL;
965 977
966 vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; 978 vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
967 vma->vm_ops = dev->driver->gem_vm_ops;
968 vma->vm_private_data = obj; 979 vma->vm_private_data = obj;
969 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); 980 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
970 vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); 981 vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
@@ -1066,6 +1077,86 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent,
1066 drm_printf_indent(p, indent, "imported=%s\n", 1077 drm_printf_indent(p, indent, "imported=%s\n",
1067 obj->import_attach ? "yes" : "no"); 1078 obj->import_attach ? "yes" : "no");
1068 1079
1069 if (obj->dev->driver->gem_print_info) 1080 if (obj->funcs && obj->funcs->print_info)
1081 obj->funcs->print_info(p, indent, obj);
1082 else if (obj->dev->driver->gem_print_info)
1070 obj->dev->driver->gem_print_info(p, indent, obj); 1083 obj->dev->driver->gem_print_info(p, indent, obj);
1071} 1084}
1085
1086/**
1087 * drm_gem_pin - Pin backing buffer in memory
1088 * @obj: GEM object
1089 *
1090 * Make sure the backing buffer is pinned in memory.
1091 *
1092 * Returns:
1093 * 0 on success or a negative error code on failure.
1094 */
1095int drm_gem_pin(struct drm_gem_object *obj)
1096{
1097 if (obj->funcs && obj->funcs->pin)
1098 return obj->funcs->pin(obj);
1099 else if (obj->dev->driver->gem_prime_pin)
1100 return obj->dev->driver->gem_prime_pin(obj);
1101 else
1102 return 0;
1103}
1104EXPORT_SYMBOL(drm_gem_pin);
1105
1106/**
1107 * drm_gem_unpin - Unpin backing buffer from memory
1108 * @obj: GEM object
1109 *
1110 * Relax the requirement that the backing buffer is pinned in memory.
1111 */
1112void drm_gem_unpin(struct drm_gem_object *obj)
1113{
1114 if (obj->funcs && obj->funcs->unpin)
1115 obj->funcs->unpin(obj);
1116 else if (obj->dev->driver->gem_prime_unpin)
1117 obj->dev->driver->gem_prime_unpin(obj);
1118}
1119EXPORT_SYMBOL(drm_gem_unpin);
1120
1121/**
1122 * drm_gem_vmap - Map buffer into kernel virtual address space
1123 * @obj: GEM object
1124 *
1125 * Returns:
1126 * A virtual pointer to a newly created GEM object or an ERR_PTR-encoded negative
1127 * error code on failure.
1128 */
1129void *drm_gem_vmap(struct drm_gem_object *obj)
1130{
1131 void *vaddr;
1132
1133 if (obj->funcs && obj->funcs->vmap)
1134 vaddr = obj->funcs->vmap(obj);
1135 else if (obj->dev->driver->gem_prime_vmap)
1136 vaddr = obj->dev->driver->gem_prime_vmap(obj);
1137 else
1138 vaddr = ERR_PTR(-EOPNOTSUPP);
1139
1140 if (!vaddr)
1141 vaddr = ERR_PTR(-ENOMEM);
1142
1143 return vaddr;
1144}
1145EXPORT_SYMBOL(drm_gem_vmap);
1146
1147/**
1148 * drm_gem_vunmap - Remove buffer mapping from kernel virtual address space
1149 * @obj: GEM object
1150 * @vaddr: Virtual address (can be NULL)
1151 */
1152void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr)
1153{
1154 if (!vaddr)
1155 return;
1156
1157 if (obj->funcs && obj->funcs->vunmap)
1158 obj->funcs->vunmap(obj, vaddr);
1159 else if (obj->dev->driver->gem_prime_vunmap)
1160 obj->dev->driver->gem_prime_vunmap(obj, vaddr);
1161}
1162EXPORT_SYMBOL(drm_gem_vunmap);