aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
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
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')
-rw-r--r--drivers/gpu/drm/drm_client.c12
-rw-r--r--drivers/gpu/drm/drm_gem.c109
-rw-r--r--drivers/gpu/drm/drm_prime.c34
3 files changed, 121 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index fc03d26fcacc..9b2bd28dde0a 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -81,8 +81,7 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
81{ 81{
82 int ret; 82 int ret;
83 83
84 if (!drm_core_check_feature(dev, DRIVER_MODESET) || 84 if (!drm_core_check_feature(dev, DRIVER_MODESET) || !dev->driver->dumb_create)
85 !dev->driver->dumb_create || !dev->driver->gem_prime_vmap)
86 return -EOPNOTSUPP; 85 return -EOPNOTSUPP;
87 86
88 if (funcs && !try_module_get(funcs->owner)) 87 if (funcs && !try_module_get(funcs->owner))
@@ -229,8 +228,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
229{ 228{
230 struct drm_device *dev = buffer->client->dev; 229 struct drm_device *dev = buffer->client->dev;
231 230
232 if (buffer->vaddr && dev->driver->gem_prime_vunmap) 231 drm_gem_vunmap(buffer->gem, buffer->vaddr);
233 dev->driver->gem_prime_vunmap(buffer->gem, buffer->vaddr);
234 232
235 if (buffer->gem) 233 if (buffer->gem)
236 drm_gem_object_put_unlocked(buffer->gem); 234 drm_gem_object_put_unlocked(buffer->gem);
@@ -283,9 +281,9 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
283 * fd_install step out of the driver backend hooks, to make that 281 * fd_install step out of the driver backend hooks, to make that
284 * final step optional for internal users. 282 * final step optional for internal users.
285 */ 283 */
286 vaddr = dev->driver->gem_prime_vmap(obj); 284 vaddr = drm_gem_vmap(obj);
287 if (!vaddr) { 285 if (IS_ERR(vaddr)) {
288 ret = -ENOMEM; 286 ret = PTR_ERR(vaddr);
289 goto err_delete; 287 goto err_delete;
290 } 288 }
291 289
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);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 6a4fe0216e27..5737cb8c6f03 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -199,7 +199,6 @@ int drm_gem_map_attach(struct dma_buf *dma_buf,
199{ 199{
200 struct drm_prime_attachment *prime_attach; 200 struct drm_prime_attachment *prime_attach;
201 struct drm_gem_object *obj = dma_buf->priv; 201 struct drm_gem_object *obj = dma_buf->priv;
202 struct drm_device *dev = obj->dev;
203 202
204 prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL); 203 prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL);
205 if (!prime_attach) 204 if (!prime_attach)
@@ -208,10 +207,7 @@ int drm_gem_map_attach(struct dma_buf *dma_buf,
208 prime_attach->dir = DMA_NONE; 207 prime_attach->dir = DMA_NONE;
209 attach->priv = prime_attach; 208 attach->priv = prime_attach;
210 209
211 if (!dev->driver->gem_prime_pin) 210 return drm_gem_pin(obj);
212 return 0;
213
214 return dev->driver->gem_prime_pin(obj);
215} 211}
216EXPORT_SYMBOL(drm_gem_map_attach); 212EXPORT_SYMBOL(drm_gem_map_attach);
217 213
@@ -228,7 +224,6 @@ void drm_gem_map_detach(struct dma_buf *dma_buf,
228{ 224{
229 struct drm_prime_attachment *prime_attach = attach->priv; 225 struct drm_prime_attachment *prime_attach = attach->priv;
230 struct drm_gem_object *obj = dma_buf->priv; 226 struct drm_gem_object *obj = dma_buf->priv;
231 struct drm_device *dev = obj->dev;
232 227
233 if (prime_attach) { 228 if (prime_attach) {
234 struct sg_table *sgt = prime_attach->sgt; 229 struct sg_table *sgt = prime_attach->sgt;
@@ -247,8 +242,7 @@ void drm_gem_map_detach(struct dma_buf *dma_buf,
247 attach->priv = NULL; 242 attach->priv = NULL;
248 } 243 }
249 244
250 if (dev->driver->gem_prime_unpin) 245 drm_gem_unpin(obj);
251 dev->driver->gem_prime_unpin(obj);
252} 246}
253EXPORT_SYMBOL(drm_gem_map_detach); 247EXPORT_SYMBOL(drm_gem_map_detach);
254 248
@@ -310,7 +304,10 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
310 if (WARN_ON(prime_attach->dir != DMA_NONE)) 304 if (WARN_ON(prime_attach->dir != DMA_NONE))
311 return ERR_PTR(-EBUSY); 305 return ERR_PTR(-EBUSY);
312 306
313 sgt = obj->dev->driver->gem_prime_get_sg_table(obj); 307 if (obj->funcs)
308 sgt = obj->funcs->get_sg_table(obj);
309 else
310 sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
314 311
315 if (!IS_ERR(sgt)) { 312 if (!IS_ERR(sgt)) {
316 if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, 313 if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
@@ -406,12 +403,13 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release);
406void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf) 403void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
407{ 404{
408 struct drm_gem_object *obj = dma_buf->priv; 405 struct drm_gem_object *obj = dma_buf->priv;
409 struct drm_device *dev = obj->dev; 406 void *vaddr;
410 407
411 if (dev->driver->gem_prime_vmap) 408 vaddr = drm_gem_vmap(obj);
412 return dev->driver->gem_prime_vmap(obj); 409 if (IS_ERR(vaddr))
413 else 410 vaddr = NULL;
414 return NULL; 411
412 return vaddr;
415} 413}
416EXPORT_SYMBOL(drm_gem_dmabuf_vmap); 414EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
417 415
@@ -426,10 +424,8 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
426void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) 424void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
427{ 425{
428 struct drm_gem_object *obj = dma_buf->priv; 426 struct drm_gem_object *obj = dma_buf->priv;
429 struct drm_device *dev = obj->dev;
430 427
431 if (dev->driver->gem_prime_vunmap) 428 drm_gem_vunmap(obj, vaddr);
432 dev->driver->gem_prime_vunmap(obj, vaddr);
433} 429}
434EXPORT_SYMBOL(drm_gem_dmabuf_vunmap); 430EXPORT_SYMBOL(drm_gem_dmabuf_vunmap);
435 431
@@ -529,7 +525,9 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev,
529 return dmabuf; 525 return dmabuf;
530 } 526 }
531 527
532 if (dev->driver->gem_prime_export) 528 if (obj->funcs && obj->funcs->export)
529 dmabuf = obj->funcs->export(obj, flags);
530 else if (dev->driver->gem_prime_export)
533 dmabuf = dev->driver->gem_prime_export(dev, obj, flags); 531 dmabuf = dev->driver->gem_prime_export(dev, obj, flags);
534 else 532 else
535 dmabuf = drm_gem_prime_export(dev, obj, flags); 533 dmabuf = drm_gem_prime_export(dev, obj, flags);