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 --- |