gem.c (728d90bdc9e480dc93913e59a0aa3c896c7aa697) gem.c (7e3c53a096a9e75b12e69f93ef1fbc7cb1b27297)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * NVIDIA Tegra DRM GEM helper functions
4 *
5 * Copyright (C) 2012 Sascha Hauer, Pengutronix
6 * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved.
7 *
8 * Based on the GEM/CMA helpers

--- 19 unchanged lines hidden (view full) ---

28}
29
30static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
31{
32 struct tegra_bo *obj = host1x_to_tegra_bo(bo);
33
34 *sgt = obj->sgt;
35
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * NVIDIA Tegra DRM GEM helper functions
4 *
5 * Copyright (C) 2012 Sascha Hauer, Pengutronix
6 * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved.
7 *
8 * Based on the GEM/CMA helpers

--- 19 unchanged lines hidden (view full) ---

28}
29
30static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
31{
32 struct tegra_bo *obj = host1x_to_tegra_bo(bo);
33
34 *sgt = obj->sgt;
35
36 return obj->paddr;
36 return obj->iova;
37}
38
39static void tegra_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt)
40{
41}
42
43static void *tegra_bo_mmap(struct host1x_bo *bo)
44{

--- 83 unchanged lines hidden (view full) ---

128 err = drm_mm_insert_node_generic(&tegra->mm,
129 bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
130 if (err < 0) {
131 dev_err(tegra->drm->dev, "out of I/O virtual memory: %d\n",
132 err);
133 goto unlock;
134 }
135
37}
38
39static void tegra_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt)
40{
41}
42
43static void *tegra_bo_mmap(struct host1x_bo *bo)
44{

--- 83 unchanged lines hidden (view full) ---

128 err = drm_mm_insert_node_generic(&tegra->mm,
129 bo->mm, bo->gem.size, PAGE_SIZE, 0, 0);
130 if (err < 0) {
131 dev_err(tegra->drm->dev, "out of I/O virtual memory: %d\n",
132 err);
133 goto unlock;
134 }
135
136 bo->paddr = bo->mm->start;
136 bo->iova = bo->mm->start;
137
137
138 bo->size = iommu_map_sg(tegra->domain, bo->paddr, bo->sgt->sgl,
138 bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
139 bo->sgt->nents, prot);
140 if (!bo->size) {
141 dev_err(tegra->drm->dev, "failed to map buffer\n");
142 err = -ENOMEM;
143 goto remove;
144 }
145
146 mutex_unlock(&tegra->mm_lock);

--- 9 unchanged lines hidden (view full) ---

156}
157
158static int tegra_bo_iommu_unmap(struct tegra_drm *tegra, struct tegra_bo *bo)
159{
160 if (!bo->mm)
161 return 0;
162
163 mutex_lock(&tegra->mm_lock);
139 bo->sgt->nents, prot);
140 if (!bo->size) {
141 dev_err(tegra->drm->dev, "failed to map buffer\n");
142 err = -ENOMEM;
143 goto remove;
144 }
145
146 mutex_unlock(&tegra->mm_lock);

--- 9 unchanged lines hidden (view full) ---

156}
157
158static int tegra_bo_iommu_unmap(struct tegra_drm *tegra, struct tegra_bo *bo)
159{
160 if (!bo->mm)
161 return 0;
162
163 mutex_lock(&tegra->mm_lock);
164 iommu_unmap(tegra->domain, bo->paddr, bo->size);
164 iommu_unmap(tegra->domain, bo->iova, bo->size);
165 drm_mm_remove_node(bo->mm);
166 mutex_unlock(&tegra->mm_lock);
167
168 kfree(bo->mm);
169
170 return 0;
171}
172

--- 31 unchanged lines hidden (view full) ---

204{
205 if (bo->pages) {
206 dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
207 DMA_FROM_DEVICE);
208 drm_gem_put_pages(&bo->gem, bo->pages, true, true);
209 sg_free_table(bo->sgt);
210 kfree(bo->sgt);
211 } else if (bo->vaddr) {
165 drm_mm_remove_node(bo->mm);
166 mutex_unlock(&tegra->mm_lock);
167
168 kfree(bo->mm);
169
170 return 0;
171}
172

--- 31 unchanged lines hidden (view full) ---

204{
205 if (bo->pages) {
206 dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
207 DMA_FROM_DEVICE);
208 drm_gem_put_pages(&bo->gem, bo->pages, true, true);
209 sg_free_table(bo->sgt);
210 kfree(bo->sgt);
211 } else if (bo->vaddr) {
212 dma_free_wc(drm->dev, bo->gem.size, bo->vaddr, bo->paddr);
212 dma_free_wc(drm->dev, bo->gem.size, bo->vaddr, bo->iova);
213 }
214}
215
216static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
217{
218 int err;
219
220 bo->pages = drm_gem_get_pages(&bo->gem);

--- 38 unchanged lines hidden (view full) ---

259 err = tegra_bo_iommu_map(tegra, bo);
260 if (err < 0) {
261 tegra_bo_free(drm, bo);
262 return err;
263 }
264 } else {
265 size_t size = bo->gem.size;
266
213 }
214}
215
216static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
217{
218 int err;
219
220 bo->pages = drm_gem_get_pages(&bo->gem);

--- 38 unchanged lines hidden (view full) ---

259 err = tegra_bo_iommu_map(tegra, bo);
260 if (err < 0) {
261 tegra_bo_free(drm, bo);
262 return err;
263 }
264 } else {
265 size_t size = bo->gem.size;
266
267 bo->vaddr = dma_alloc_wc(drm->dev, size, &bo->paddr,
267 bo->vaddr = dma_alloc_wc(drm->dev, size, &bo->iova,
268 GFP_KERNEL | __GFP_NOWARN);
269 if (!bo->vaddr) {
270 dev_err(drm->dev,
271 "failed to allocate buffer of size %zu\n",
272 size);
273 return -ENOMEM;
274 }
275 }

--- 84 unchanged lines hidden (view full) ---

360 if (err < 0)
361 goto detach;
362 } else {
363 if (bo->sgt->nents > 1) {
364 err = -EINVAL;
365 goto detach;
366 }
367
268 GFP_KERNEL | __GFP_NOWARN);
269 if (!bo->vaddr) {
270 dev_err(drm->dev,
271 "failed to allocate buffer of size %zu\n",
272 size);
273 return -ENOMEM;
274 }
275 }

--- 84 unchanged lines hidden (view full) ---

360 if (err < 0)
361 goto detach;
362 } else {
363 if (bo->sgt->nents > 1) {
364 err = -EINVAL;
365 goto detach;
366 }
367
368 bo->paddr = sg_dma_address(bo->sgt->sgl);
368 bo->iova = sg_dma_address(bo->sgt->sgl);
369 }
370
371 bo->gem.import_attach = attach;
372
373 return bo;
374
375detach:
376 if (!IS_ERR_OR_NULL(bo->sgt))

--- 79 unchanged lines hidden (view full) ---

456 /*
457 * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(),
458 * and set the vm_pgoff (used as a fake buffer offset by DRM)
459 * to 0 as we want to map the whole buffer.
460 */
461 vma->vm_flags &= ~VM_PFNMAP;
462 vma->vm_pgoff = 0;
463
369 }
370
371 bo->gem.import_attach = attach;
372
373 return bo;
374
375detach:
376 if (!IS_ERR_OR_NULL(bo->sgt))

--- 79 unchanged lines hidden (view full) ---

456 /*
457 * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(),
458 * and set the vm_pgoff (used as a fake buffer offset by DRM)
459 * to 0 as we want to map the whole buffer.
460 */
461 vma->vm_flags &= ~VM_PFNMAP;
462 vma->vm_pgoff = 0;
463
464 err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr,
464 err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->iova,
465 gem->size);
466 if (err < 0) {
467 drm_gem_vm_close(vma);
468 return err;
469 }
470
471 vma->vm_pgoff = vm_pgoff;
472 } else {

--- 45 unchanged lines hidden (view full) ---

518 sg_set_page(sg, bo->pages[i], PAGE_SIZE, 0);
519
520 if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
521 goto free;
522 } else {
523 if (sg_alloc_table(sgt, 1, GFP_KERNEL))
524 goto free;
525
465 gem->size);
466 if (err < 0) {
467 drm_gem_vm_close(vma);
468 return err;
469 }
470
471 vma->vm_pgoff = vm_pgoff;
472 } else {

--- 45 unchanged lines hidden (view full) ---

518 sg_set_page(sg, bo->pages[i], PAGE_SIZE, 0);
519
520 if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
521 goto free;
522 } else {
523 if (sg_alloc_table(sgt, 1, GFP_KERNEL))
524 goto free;
525
526 sg_dma_address(sgt->sgl) = bo->paddr;
526 sg_dma_address(sgt->sgl) = bo->iova;
527 sg_dma_len(sgt->sgl) = gem->size;
528 }
529
530 return sgt;
531
532free:
533 sg_free_table(sgt);
534 kfree(sgt);

--- 132 unchanged lines hidden ---
527 sg_dma_len(sgt->sgl) = gem->size;
528 }
529
530 return sgt;
531
532free:
533 sg_free_table(sgt);
534 kfree(sgt);

--- 132 unchanged lines hidden ---