]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/exynos/exynos_drm_gem.c
drm/exynos: cleanup name of gem object for exynos_drm
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / exynos / exynos_drm_gem.c
CommitLineData
1c248b7d
ID
1/* exynos_drm_gem.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Author: Inki Dae <inki.dae@samsung.com>
5 *
d81aecb5
ID
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
1c248b7d
ID
10 */
11
760285e7 12#include <drm/drmP.h>
0de23977 13#include <drm/drm_vma_manager.h>
1c248b7d 14
2b35892e 15#include <linux/shmem_fs.h>
01ed50dd 16#include <linux/dma-buf.h>
1c248b7d
ID
17#include <drm/exynos_drm.h>
18
19#include "exynos_drm_drv.h"
20#include "exynos_drm_gem.h"
3fec4532 21#include "exynos_drm_iommu.h"
1c248b7d 22
813fd67b 23static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
2a8cb489 24{
813fd67b 25 struct drm_device *dev = exynos_gem->base.dev;
2a8cb489
JS
26 enum dma_attr attr;
27 unsigned int nr_pages;
28
813fd67b 29 if (exynos_gem->dma_addr) {
2a8cb489
JS
30 DRM_DEBUG_KMS("already allocated.\n");
31 return 0;
32 }
33
813fd67b 34 init_dma_attrs(&exynos_gem->dma_attrs);
2a8cb489
JS
35
36 /*
37 * if EXYNOS_BO_CONTIG, fully physically contiguous memory
38 * region will be allocated else physically contiguous
39 * as possible.
40 */
813fd67b
JS
41 if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
42 dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &exynos_gem->dma_attrs);
2a8cb489
JS
43
44 /*
45 * if EXYNOS_BO_WC or EXYNOS_BO_NONCACHABLE, writecombine mapping
46 * else cachable mapping.
47 */
813fd67b
JS
48 if (exynos_gem->flags & EXYNOS_BO_WC ||
49 !(exynos_gem->flags & EXYNOS_BO_CACHABLE))
2a8cb489
JS
50 attr = DMA_ATTR_WRITE_COMBINE;
51 else
52 attr = DMA_ATTR_NON_CONSISTENT;
53
813fd67b
JS
54 dma_set_attr(attr, &exynos_gem->dma_attrs);
55 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &exynos_gem->dma_attrs);
2a8cb489 56
813fd67b 57 nr_pages = exynos_gem->size >> PAGE_SHIFT;
2a8cb489
JS
58
59 if (!is_drm_iommu_supported(dev)) {
813fd67b
JS
60 exynos_gem->pages = drm_calloc_large(nr_pages,
61 sizeof(struct page *));
62 if (!exynos_gem->pages) {
2a8cb489
JS
63 DRM_ERROR("failed to allocate pages.\n");
64 return -ENOMEM;
65 }
333e8e58 66 }
2a8cb489 67
813fd67b
JS
68 exynos_gem->cookie = dma_alloc_attrs(dev->dev, exynos_gem->size,
69 &exynos_gem->dma_addr, GFP_KERNEL,
70 &exynos_gem->dma_attrs);
71 if (!exynos_gem->cookie) {
333e8e58 72 DRM_ERROR("failed to allocate buffer.\n");
813fd67b
JS
73 if (exynos_gem->pages)
74 drm_free_large(exynos_gem->pages);
333e8e58
JS
75 return -ENOMEM;
76 }
77
813fd67b 78 if (exynos_gem->pages) {
333e8e58
JS
79 dma_addr_t start_addr;
80 unsigned int i = 0;
2a8cb489 81
813fd67b 82 start_addr = exynos_gem->dma_addr;
2a8cb489 83 while (i < nr_pages) {
813fd67b
JS
84 exynos_gem->pages[i] =
85 pfn_to_page(dma_to_pfn(dev->dev, start_addr));
2a8cb489
JS
86 start_addr += PAGE_SIZE;
87 i++;
88 }
89 } else {
813fd67b 90 exynos_gem->pages = exynos_gem->cookie;
2a8cb489
JS
91 }
92
93 DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
813fd67b 94 (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
2a8cb489
JS
95
96 return 0;
97}
98
813fd67b 99static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
2a8cb489 100{
813fd67b 101 struct drm_device *dev = exynos_gem->base.dev;
2a8cb489 102
813fd67b 103 if (!exynos_gem->dma_addr) {
2a8cb489
JS
104 DRM_DEBUG_KMS("dma_addr is invalid.\n");
105 return;
106 }
107
108 DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
813fd67b 109 (unsigned long)exynos_gem->dma_addr, exynos_gem->size);
2a8cb489 110
813fd67b
JS
111 dma_free_attrs(dev->dev, exynos_gem->size, exynos_gem->cookie,
112 (dma_addr_t)exynos_gem->dma_addr,
113 &exynos_gem->dma_attrs);
333e8e58
JS
114
115 if (!is_drm_iommu_supported(dev))
813fd67b 116 drm_free_large(exynos_gem->pages);
2a8cb489
JS
117}
118
2364839a
JS
119static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
120 struct drm_file *file_priv,
121 unsigned int *handle)
1c248b7d 122{
1c248b7d
ID
123 int ret;
124
1c248b7d
ID
125 /*
126 * allocate a id of idr table where the obj is registered
127 * and handle has the id what user can see.
128 */
129 ret = drm_gem_handle_create(file_priv, obj, handle);
130 if (ret)
2364839a 131 return ret;
1c248b7d
ID
132
133 DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle);
134
135 /* drop reference from allocate - handle holds it now. */
136 drm_gem_object_unreference_unlocked(obj);
137
2364839a
JS
138 return 0;
139}
140
813fd67b 141void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem)
2364839a 142{
813fd67b 143 struct drm_gem_object *obj = &exynos_gem->base;
2364839a 144
a8e11d1c 145 DRM_DEBUG_KMS("handle count = %d\n", obj->handle_count);
1c248b7d 146
c374e731
ID
147 /*
148 * do not release memory region from exporter.
149 *
150 * the region will be released by exporter
151 * once dmabuf's refcount becomes 0.
152 */
153 if (obj->import_attach)
813fd67b 154 drm_prime_gem_destroy(obj, exynos_gem->sgt);
7c93537a 155 else
813fd67b 156 exynos_drm_free_buf(exynos_gem);
2b35892e 157
2364839a 158 /* release file pointer to gem object. */
1c248b7d
ID
159 drm_gem_object_release(obj);
160
813fd67b 161 kfree(exynos_gem);
2364839a
JS
162}
163
a4f19aaa
ID
164unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
165 unsigned int gem_handle,
166 struct drm_file *file_priv)
167{
813fd67b 168 struct exynos_drm_gem *exynos_gem;
a4f19aaa
ID
169 struct drm_gem_object *obj;
170
171 obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
172 if (!obj) {
173 DRM_ERROR("failed to lookup gem object.\n");
174 return 0;
175 }
176
813fd67b 177 exynos_gem = to_exynos_gem(obj);
a4f19aaa
ID
178
179 drm_gem_object_unreference_unlocked(obj);
180
813fd67b 181 return exynos_gem->size;
a4f19aaa
ID
182}
183
813fd67b
JS
184static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
185 unsigned long size)
2364839a 186{
813fd67b 187 struct exynos_drm_gem *exynos_gem;
2364839a
JS
188 struct drm_gem_object *obj;
189 int ret;
190
813fd67b
JS
191 exynos_gem = kzalloc(sizeof(*exynos_gem), GFP_KERNEL);
192 if (!exynos_gem)
5f3f4266 193 return ERR_PTR(-ENOMEM);
2364839a 194
813fd67b
JS
195 exynos_gem->size = size;
196 obj = &exynos_gem->base;
2364839a
JS
197
198 ret = drm_gem_object_init(dev, obj, size);
199 if (ret < 0) {
200 DRM_ERROR("failed to initialize gem object\n");
813fd67b 201 kfree(exynos_gem);
5f3f4266 202 return ERR_PTR(ret);
2364839a
JS
203 }
204
48cf53f4
JS
205 ret = drm_gem_create_mmap_offset(obj);
206 if (ret < 0) {
207 drm_gem_object_release(obj);
813fd67b 208 kfree(exynos_gem);
48cf53f4
JS
209 return ERR_PTR(ret);
210 }
211
2364839a
JS
212 DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
213
813fd67b 214 return exynos_gem;
1c248b7d
ID
215}
216
813fd67b
JS
217struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev,
218 unsigned int flags,
219 unsigned long size)
f088d5a9 220{
813fd67b 221 struct exynos_drm_gem *exynos_gem;
2b35892e 222 int ret;
f088d5a9 223
c4130bcd
JS
224 if (flags & ~(EXYNOS_BO_MASK)) {
225 DRM_ERROR("invalid flags.\n");
226 return ERR_PTR(-EINVAL);
227 }
228
dcf9af82
ID
229 if (!size) {
230 DRM_ERROR("invalid size.\n");
231 return ERR_PTR(-EINVAL);
232 }
233
eb57da88 234 size = roundup(size, PAGE_SIZE);
f088d5a9 235
813fd67b
JS
236 exynos_gem = exynos_drm_gem_init(dev, size);
237 if (IS_ERR(exynos_gem))
238 return exynos_gem;
2b35892e
ID
239
240 /* set memory type and cache attribute from user side. */
813fd67b 241 exynos_gem->flags = flags;
2b35892e 242
813fd67b 243 ret = exynos_drm_alloc_buf(exynos_gem);
2a8cb489 244 if (ret < 0) {
813fd67b
JS
245 drm_gem_object_release(&exynos_gem->base);
246 kfree(exynos_gem);
2a8cb489
JS
247 return ERR_PTR(ret);
248 }
f088d5a9 249
813fd67b 250 return exynos_gem;
f088d5a9
ID
251}
252
1c248b7d 253int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
ee5e770e 254 struct drm_file *file_priv)
1c248b7d
ID
255{
256 struct drm_exynos_gem_create *args = data;
813fd67b 257 struct exynos_drm_gem *exynos_gem;
2364839a 258 int ret;
1c248b7d 259
813fd67b
JS
260 exynos_gem = exynos_drm_gem_create(dev, args->flags, args->size);
261 if (IS_ERR(exynos_gem))
262 return PTR_ERR(exynos_gem);
1c248b7d 263
813fd67b
JS
264 ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
265 &args->handle);
2364839a 266 if (ret) {
813fd67b 267 exynos_drm_gem_destroy(exynos_gem);
2364839a
JS
268 return ret;
269 }
270
1c248b7d
ID
271 return 0;
272}
273
d87342c1 274dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
f0b1bda7 275 unsigned int gem_handle,
d87342c1 276 struct drm_file *filp)
f0b1bda7 277{
813fd67b 278 struct exynos_drm_gem *exynos_gem;
f0b1bda7
ID
279 struct drm_gem_object *obj;
280
d87342c1 281 obj = drm_gem_object_lookup(dev, filp, gem_handle);
f0b1bda7
ID
282 if (!obj) {
283 DRM_ERROR("failed to lookup gem object.\n");
284 return ERR_PTR(-EINVAL);
285 }
286
813fd67b 287 exynos_gem = to_exynos_gem(obj);
f0b1bda7 288
813fd67b 289 return &exynos_gem->dma_addr;
f0b1bda7
ID
290}
291
292void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
293 unsigned int gem_handle,
d87342c1 294 struct drm_file *filp)
f0b1bda7 295{
f0b1bda7
ID
296 struct drm_gem_object *obj;
297
d87342c1 298 obj = drm_gem_object_lookup(dev, filp, gem_handle);
f0b1bda7
ID
299 if (!obj) {
300 DRM_ERROR("failed to lookup gem object.\n");
301 return;
302 }
303
f0b1bda7
ID
304 drm_gem_object_unreference_unlocked(obj);
305
306 /*
307 * decrease obj->refcount one more time because we has already
308 * increased it at exynos_drm_gem_get_dma_addr().
309 */
310 drm_gem_object_unreference_unlocked(obj);
311}
312
813fd67b 313static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,
ee5e770e 314 struct vm_area_struct *vma)
1c248b7d 315{
813fd67b 316 struct drm_device *drm_dev = exynos_gem->base.dev;
0519f9a1 317 unsigned long vm_size;
5b07c660 318 int ret;
1c248b7d 319
832316c7
ID
320 vma->vm_flags &= ~VM_PFNMAP;
321 vma->vm_pgoff = 0;
1c248b7d 322
0519f9a1 323 vm_size = vma->vm_end - vma->vm_start;
2b35892e 324
1c248b7d 325 /* check if user-requested size is valid. */
813fd67b 326 if (vm_size > exynos_gem->size)
1c248b7d
ID
327 return -EINVAL;
328
813fd67b
JS
329 ret = dma_mmap_attrs(drm_dev->dev, vma, exynos_gem->pages,
330 exynos_gem->dma_addr, exynos_gem->size,
331 &exynos_gem->dma_attrs);
5b07c660
ID
332 if (ret < 0) {
333 DRM_ERROR("failed to mmap.\n");
334 return ret;
335 }
336
1c248b7d
ID
337 return 0;
338}
339
40cd7e0c
ID
340int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
341 struct drm_file *file_priv)
b4cfd4dd 342{
813fd67b 343 struct exynos_drm_gem *exynos_gem;
40cd7e0c
ID
344 struct drm_exynos_gem_info *args = data;
345 struct drm_gem_object *obj;
346
347 mutex_lock(&dev->struct_mutex);
348
349 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
350 if (!obj) {
351 DRM_ERROR("failed to lookup gem object.\n");
352 mutex_unlock(&dev->struct_mutex);
353 return -EINVAL;
354 }
355
813fd67b 356 exynos_gem = to_exynos_gem(obj);
40cd7e0c 357
813fd67b
JS
358 args->flags = exynos_gem->flags;
359 args->size = exynos_gem->size;
40cd7e0c
ID
360
361 drm_gem_object_unreference(obj);
362 mutex_unlock(&dev->struct_mutex);
363
364 return 0;
365}
366
2a3098ff
ID
367int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
368 struct sg_table *sgt,
369 enum dma_data_direction dir)
370{
371 int nents;
372
373 mutex_lock(&drm_dev->struct_mutex);
374
375 nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
376 if (!nents) {
377 DRM_ERROR("failed to map sgl with dma.\n");
378 mutex_unlock(&drm_dev->struct_mutex);
379 return nents;
380 }
381
382 mutex_unlock(&drm_dev->struct_mutex);
383 return 0;
384}
385
386void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
387 struct sg_table *sgt,
388 enum dma_data_direction dir)
389{
390 dma_unmap_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
391}
392
ee5e770e 393void exynos_drm_gem_free_object(struct drm_gem_object *obj)
1c248b7d 394{
813fd67b 395 exynos_drm_gem_destroy(to_exynos_gem(obj));
1c248b7d
ID
396}
397
398int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
ee5e770e
JS
399 struct drm_device *dev,
400 struct drm_mode_create_dumb *args)
1c248b7d 401{
813fd67b 402 struct exynos_drm_gem *exynos_gem;
333e8e58 403 unsigned int flags;
2364839a 404 int ret;
1c248b7d 405
1c248b7d 406 /*
c6b78bc8 407 * allocate memory to be used for framebuffer.
1c248b7d
ID
408 * - this callback would be called by user application
409 * with DRM_IOCTL_MODE_CREATE_DUMB command.
410 */
411
3fd6b694 412 args->pitch = args->width * ((args->bpp + 7) / 8);
7da5907c 413 args->size = args->pitch * args->height;
1c248b7d 414
333e8e58
JS
415 if (is_drm_iommu_supported(dev))
416 flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
417 else
418 flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
3fec4532 419
813fd67b
JS
420 exynos_gem = exynos_drm_gem_create(dev, flags, args->size);
421 if (IS_ERR(exynos_gem)) {
122beea8 422 dev_warn(dev->dev, "FB allocation failed.\n");
813fd67b 423 return PTR_ERR(exynos_gem);
122beea8 424 }
1c248b7d 425
813fd67b
JS
426 ret = exynos_drm_gem_handle_create(&exynos_gem->base, file_priv,
427 &args->handle);
2364839a 428 if (ret) {
813fd67b 429 exynos_drm_gem_destroy(exynos_gem);
2364839a
JS
430 return ret;
431 }
432
1c248b7d
ID
433 return 0;
434}
435
436int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
ee5e770e
JS
437 struct drm_device *dev, uint32_t handle,
438 uint64_t *offset)
1c248b7d 439{
1c248b7d 440 struct drm_gem_object *obj;
2d91cf17 441 int ret = 0;
1c248b7d 442
1c248b7d
ID
443 mutex_lock(&dev->struct_mutex);
444
445 /*
446 * get offset of memory allocated for drm framebuffer.
447 * - this callback would be called by user application
448 * with DRM_IOCTL_MODE_MAP_DUMB command.
449 */
450
451 obj = drm_gem_object_lookup(dev, file_priv, handle);
452 if (!obj) {
453 DRM_ERROR("failed to lookup gem object.\n");
2d91cf17
JS
454 ret = -EINVAL;
455 goto unlock;
1c248b7d
ID
456 }
457
0de23977 458 *offset = drm_vma_node_offset_addr(&obj->vma_node);
1c248b7d
ID
459 DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
460
2d91cf17
JS
461 drm_gem_object_unreference(obj);
462unlock:
1c248b7d 463 mutex_unlock(&dev->struct_mutex);
2d91cf17 464 return ret;
1c248b7d
ID
465}
466
467int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
468{
469 struct drm_gem_object *obj = vma->vm_private_data;
813fd67b 470 struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
0e9a2ee3 471 unsigned long pfn;
1c248b7d
ID
472 pgoff_t page_offset;
473 int ret;
474
475 page_offset = ((unsigned long)vmf->virtual_address -
476 vma->vm_start) >> PAGE_SHIFT;
477
813fd67b 478 if (page_offset >= (exynos_gem->size >> PAGE_SHIFT)) {
0e9a2ee3
JS
479 DRM_ERROR("invalid page offset\n");
480 ret = -EINVAL;
481 goto out;
482 }
1c248b7d 483
813fd67b 484 pfn = page_to_pfn(exynos_gem->pages[page_offset]);
0e9a2ee3
JS
485 ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
486
487out:
23597e26
JS
488 switch (ret) {
489 case 0:
490 case -ERESTARTSYS:
491 case -EINTR:
492 return VM_FAULT_NOPAGE;
493 case -ENOMEM:
494 return VM_FAULT_OOM;
495 default:
496 return VM_FAULT_SIGBUS;
497 }
1c248b7d
ID
498}
499
500int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
501{
813fd67b 502 struct exynos_drm_gem *exynos_gem;
c01d73fa 503 struct drm_gem_object *obj;
1c248b7d
ID
504 int ret;
505
1c248b7d
ID
506 /* set vm_area_struct. */
507 ret = drm_gem_mmap(filp, vma);
508 if (ret < 0) {
509 DRM_ERROR("failed to mmap.\n");
510 return ret;
511 }
512
c01d73fa 513 obj = vma->vm_private_data;
813fd67b 514 exynos_gem = to_exynos_gem(obj);
c01d73fa 515
813fd67b 516 DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);
211b8878
JS
517
518 /* non-cachable as default. */
813fd67b 519 if (exynos_gem->flags & EXYNOS_BO_CACHABLE)
211b8878 520 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
813fd67b 521 else if (exynos_gem->flags & EXYNOS_BO_WC)
211b8878
JS
522 vma->vm_page_prot =
523 pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
524 else
525 vma->vm_page_prot =
526 pgprot_noncached(vm_get_page_prot(vma->vm_flags));
c01d73fa 527
813fd67b 528 ret = exynos_drm_gem_mmap_buffer(exynos_gem, vma);
832316c7
ID
529 if (ret)
530 goto err_close_vm;
531
532 return ret;
533
534err_close_vm:
535 drm_gem_vm_close(vma);
832316c7 536
1c248b7d
ID
537 return ret;
538}
01ed50dd
JS
539
540/* low-level interface prime helpers */
541struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
542{
813fd67b 543 struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
01ed50dd
JS
544 int npages;
545
813fd67b 546 npages = exynos_gem->size >> PAGE_SHIFT;
01ed50dd 547
813fd67b 548 return drm_prime_pages_to_sg(exynos_gem->pages, npages);
01ed50dd
JS
549}
550
551struct drm_gem_object *
552exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
553 struct dma_buf_attachment *attach,
554 struct sg_table *sgt)
555{
813fd67b 556 struct exynos_drm_gem *exynos_gem;
01ed50dd
JS
557 int npages;
558 int ret;
559
813fd67b
JS
560 exynos_gem = exynos_drm_gem_init(dev, attach->dmabuf->size);
561 if (IS_ERR(exynos_gem)) {
562 ret = PTR_ERR(exynos_gem);
50002d4c 563 return ERR_PTR(ret);
2a8cb489 564 }
01ed50dd 565
813fd67b 566 exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
01ed50dd 567
813fd67b
JS
568 npages = exynos_gem->size >> PAGE_SHIFT;
569 exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
570 if (!exynos_gem->pages) {
01ed50dd
JS
571 ret = -ENOMEM;
572 goto err;
573 }
574
813fd67b
JS
575 ret = drm_prime_sg_to_page_addr_arrays(sgt, exynos_gem->pages, NULL,
576 npages);
01ed50dd
JS
577 if (ret < 0)
578 goto err_free_large;
579
813fd67b 580 exynos_gem->sgt = sgt;
7c93537a 581
01ed50dd
JS
582 if (sgt->nents == 1) {
583 /* always physically continuous memory if sgt->nents is 1. */
813fd67b 584 exynos_gem->flags |= EXYNOS_BO_CONTIG;
01ed50dd
JS
585 } else {
586 /*
587 * this case could be CONTIG or NONCONTIG type but for now
588 * sets NONCONTIG.
589 * TODO. we have to find a way that exporter can notify
590 * the type of its own buffer to importer.
591 */
813fd67b 592 exynos_gem->flags |= EXYNOS_BO_NONCONTIG;
01ed50dd
JS
593 }
594
813fd67b 595 return &exynos_gem->base;
01ed50dd
JS
596
597err_free_large:
813fd67b 598 drm_free_large(exynos_gem->pages);
01ed50dd 599err:
813fd67b
JS
600 drm_gem_object_release(&exynos_gem->base);
601 kfree(exynos_gem);
01ed50dd
JS
602 return ERR_PTR(ret);
603}
604
605void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj)
606{
607 return NULL;
608}
609
610void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
611{
612 /* Nothing to do */
613}