Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.4-rc7 119 lines 2.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0 OR MIT 2/* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */ 3 4#include <drm/drm_prime.h> 5#include <linux/pagemap.h> 6#include <linux/dma-mapping.h> 7 8#include "lima_object.h" 9 10void lima_bo_destroy(struct lima_bo *bo) 11{ 12 if (bo->sgt) { 13 kfree(bo->pages); 14 drm_prime_gem_destroy(&bo->gem, bo->sgt); 15 } else { 16 if (bo->pages_dma_addr) { 17 int i, npages = bo->gem.size >> PAGE_SHIFT; 18 19 for (i = 0; i < npages; i++) { 20 if (bo->pages_dma_addr[i]) 21 dma_unmap_page(bo->gem.dev->dev, 22 bo->pages_dma_addr[i], 23 PAGE_SIZE, DMA_BIDIRECTIONAL); 24 } 25 } 26 27 if (bo->pages) 28 drm_gem_put_pages(&bo->gem, bo->pages, true, true); 29 } 30 31 kfree(bo->pages_dma_addr); 32 drm_gem_object_release(&bo->gem); 33 kfree(bo); 34} 35 36static struct lima_bo *lima_bo_create_struct(struct lima_device *dev, u32 size, u32 flags) 37{ 38 struct lima_bo *bo; 39 int err; 40 41 size = PAGE_ALIGN(size); 42 43 bo = kzalloc(sizeof(*bo), GFP_KERNEL); 44 if (!bo) 45 return ERR_PTR(-ENOMEM); 46 47 mutex_init(&bo->lock); 48 INIT_LIST_HEAD(&bo->va); 49 50 err = drm_gem_object_init(dev->ddev, &bo->gem, size); 51 if (err) { 52 kfree(bo); 53 return ERR_PTR(err); 54 } 55 56 return bo; 57} 58 59struct lima_bo *lima_bo_create(struct lima_device *dev, u32 size, 60 u32 flags, struct sg_table *sgt) 61{ 62 int i, err; 63 size_t npages; 64 struct lima_bo *bo, *ret; 65 66 bo = lima_bo_create_struct(dev, size, flags); 67 if (IS_ERR(bo)) 68 return bo; 69 70 npages = bo->gem.size >> PAGE_SHIFT; 71 72 bo->pages_dma_addr = kcalloc(npages, sizeof(dma_addr_t), GFP_KERNEL); 73 if (!bo->pages_dma_addr) { 74 ret = ERR_PTR(-ENOMEM); 75 goto err_out; 76 } 77 78 if (sgt) { 79 bo->sgt = sgt; 80 81 bo->pages = kcalloc(npages, sizeof(*bo->pages), GFP_KERNEL); 82 if (!bo->pages) { 83 ret = ERR_PTR(-ENOMEM); 84 goto err_out; 85 } 86 87 err = drm_prime_sg_to_page_addr_arrays( 88 sgt, bo->pages, bo->pages_dma_addr, npages); 89 if (err) { 90 ret = ERR_PTR(err); 91 goto err_out; 92 } 93 } else { 94 mapping_set_gfp_mask(bo->gem.filp->f_mapping, GFP_DMA32); 95 bo->pages = drm_gem_get_pages(&bo->gem); 96 if (IS_ERR(bo->pages)) { 97 ret = ERR_CAST(bo->pages); 98 bo->pages = NULL; 99 goto err_out; 100 } 101 102 for (i = 0; i < npages; i++) { 103 dma_addr_t addr = dma_map_page(dev->dev, bo->pages[i], 0, 104 PAGE_SIZE, DMA_BIDIRECTIONAL); 105 if (dma_mapping_error(dev->dev, addr)) { 106 ret = ERR_PTR(-EFAULT); 107 goto err_out; 108 } 109 bo->pages_dma_addr[i] = addr; 110 } 111 112 } 113 114 return bo; 115 116err_out: 117 lima_bo_destroy(bo); 118 return ret; 119}