1de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen/* 2de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * NVIDIA Tegra DRM GEM helper functions 3de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * 4de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (C) 2012 Sascha Hauer, Pengutronix 5de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved. 6de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * 7de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Based on the GEM/CMA helpers 8de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * 9de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * Copyright (c) 2011 Samsung Electronics Co., Ltd. 10de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen * 119a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * This program is free software; you can redistribute it and/or modify 129a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * it under the terms of the GNU General Public License version 2 as 139a2ac2dcdc4baa63c913377f9856993498398025Thierry Reding * published by the Free Software Foundation. 14de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen */ 15de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding#include <linux/dma-buf.h> 17773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding#include <drm/tegra_drm.h> 18773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding 19d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding#include "drm.h" 20de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen#include "gem.h" 21de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 223be8274341499cfc258eddda29f626d7be10dde5Thierry Redingstatic inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo) 23de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 24de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return container_of(bo, struct tegra_bo, base); 25de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 26de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 27de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_put(struct host1x_bo *bo) 28de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 293be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct tegra_bo *obj = host1x_to_tegra_bo(bo); 30de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct drm_device *drm = obj->gem.dev; 31de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 32de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_lock(&drm->struct_mutex); 33de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_unreference(&obj->gem); 34de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_unlock(&drm->struct_mutex); 35de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 36de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 37de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt) 38de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 393be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct tegra_bo *obj = host1x_to_tegra_bo(bo); 40de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 41de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return obj->paddr; 42de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 43de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 44de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_unpin(struct host1x_bo *bo, struct sg_table *sgt) 45de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 46de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 47de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 48de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void *tegra_bo_mmap(struct host1x_bo *bo) 49de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 503be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct tegra_bo *obj = host1x_to_tegra_bo(bo); 51de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 52de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return obj->vaddr; 53de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 54de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 55de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_munmap(struct host1x_bo *bo, void *addr) 56de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 57de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 58de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 59de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page) 60de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 613be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct tegra_bo *obj = host1x_to_tegra_bo(bo); 62de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 63de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return obj->vaddr + page * PAGE_SIZE; 64de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 65de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 66de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page, 67de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen void *addr) 68de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 69de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 70de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 71de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic struct host1x_bo *tegra_bo_get(struct host1x_bo *bo) 72de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 733be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct tegra_bo *obj = host1x_to_tegra_bo(bo); 74de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct drm_device *drm = obj->gem.dev; 75de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 76de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_lock(&drm->struct_mutex); 77de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_reference(&obj->gem); 78de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_unlock(&drm->struct_mutex); 79de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 80de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return bo; 81de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 82de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 83425c0fdc427440fdaf039a649eab713d932fa368Thierry Redingstatic const struct host1x_bo_ops tegra_bo_ops = { 84de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .get = tegra_bo_get, 85de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .put = tegra_bo_put, 86de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .pin = tegra_bo_pin, 87de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .unpin = tegra_bo_unpin, 88de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .mmap = tegra_bo_mmap, 89de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .munmap = tegra_bo_munmap, 90de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .kmap = tegra_bo_kmap, 91de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .kunmap = tegra_bo_kunmap, 92de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}; 93de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 94de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstatic void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo) 95de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 96de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen dma_free_writecombine(drm->dev, bo->gem.size, bo->vaddr, bo->paddr); 97de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 98de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 99773af77fc479fd454c3f6836f86bf63996545cf4Thierry Redingstruct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size, 100773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding unsigned long flags) 101de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 102de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo; 103de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen int err; 104de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 105de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen bo = kzalloc(sizeof(*bo), GFP_KERNEL); 106de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (!bo) 107de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return ERR_PTR(-ENOMEM); 108de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 109de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen host1x_bo_init(&bo->base, &tegra_bo_ops); 110de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen size = round_up(size, PAGE_SIZE); 111de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 112de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, 113de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen GFP_KERNEL | __GFP_NOWARN); 114de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (!bo->vaddr) { 115de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen dev_err(drm->dev, "failed to allocate buffer with size %u\n", 116de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen size); 117de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen err = -ENOMEM; 118de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen goto err_dma; 119de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen } 120de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 121de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen err = drm_gem_object_init(drm, &bo->gem, size); 122de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (err) 123de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen goto err_init; 124de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 125de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen err = drm_gem_create_mmap_offset(&bo->gem); 126de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (err) 127de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen goto err_mmap; 128de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 129773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding if (flags & DRM_TEGRA_GEM_CREATE_TILED) 130c134f019abcfaa1cb6e07f6154e92a4f8ce8ddd8Thierry Reding bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED; 131773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding 132db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP) 133db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding bo->flags |= TEGRA_BO_BOTTOM_UP; 134db7fbdfd25ee009165b6c3b80a9d1c6d8534ad94Thierry Reding 135de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return bo; 136de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 137de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_mmap: 138de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_release(&bo->gem); 139de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_init: 140de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen tegra_bo_destroy(drm, bo); 141de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr_dma: 142de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen kfree(bo); 143de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 144de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return ERR_PTR(err); 145de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 146de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 147de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenstruct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, 1483be8274341499cfc258eddda29f626d7be10dde5Thierry Reding struct drm_device *drm, 1493be8274341499cfc258eddda29f626d7be10dde5Thierry Reding unsigned int size, 150773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding unsigned long flags, 1513be8274341499cfc258eddda29f626d7be10dde5Thierry Reding unsigned int *handle) 152de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 153de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo; 154de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen int ret; 155de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 156773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding bo = tegra_bo_create(drm, size, flags); 157de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (IS_ERR(bo)) 158de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return bo; 159de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 160de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen ret = drm_gem_handle_create(file, &bo->gem, handle); 161de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (ret) 162de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen goto err; 163de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 164de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_unreference_unlocked(&bo->gem); 165de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 166de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return bo; 167de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 168de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenerr: 169de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen tegra_bo_free_object(&bo->gem); 170de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return ERR_PTR(ret); 171de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 172de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 173540457cc1fc14707f60b0eddf9df2904ba75c269Thierry Redingstatic struct tegra_bo *tegra_bo_import(struct drm_device *drm, 174540457cc1fc14707f60b0eddf9df2904ba75c269Thierry Reding struct dma_buf *buf) 1753800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 1763800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct dma_buf_attachment *attach; 1773800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct tegra_bo *bo; 1783800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding ssize_t size; 1793800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding int err; 1803800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 1813800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding bo = kzalloc(sizeof(*bo), GFP_KERNEL); 1823800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (!bo) 1833800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return ERR_PTR(-ENOMEM); 1843800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 1853800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding host1x_bo_init(&bo->base, &tegra_bo_ops); 1863800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding size = round_up(buf->size, PAGE_SIZE); 1873800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 1883800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = drm_gem_object_init(drm, &bo->gem, size); 1893800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (err < 0) 1903800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto free; 1913800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 1923800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = drm_gem_create_mmap_offset(&bo->gem); 1933800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (err < 0) 1943800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto release; 1953800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 1963800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding attach = dma_buf_attach(buf, drm->dev); 1973800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (IS_ERR(attach)) { 1983800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = PTR_ERR(attach); 1993800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto free_mmap; 2003800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 2013800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2023800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding get_dma_buf(buf); 2033800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2043800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding bo->sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE); 2053800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (!bo->sgt) { 2063800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = -ENOMEM; 2073800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto detach; 2083800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 2093800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2103800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (IS_ERR(bo->sgt)) { 2113800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = PTR_ERR(bo->sgt); 2123800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto detach; 2133800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 2143800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2153800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (bo->sgt->nents > 1) { 2163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding err = -EINVAL; 2173800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding goto detach; 2183800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 2193800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2203800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding bo->paddr = sg_dma_address(bo->sgt->sgl); 2213800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding bo->gem.import_attach = attach; 2223800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2233800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return bo; 2243800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2253800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingdetach: 2263800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (!IS_ERR_OR_NULL(bo->sgt)) 2273800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding dma_buf_unmap_attachment(attach, bo->sgt, DMA_TO_DEVICE); 2283800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2293800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding dma_buf_detach(buf, attach); 2303800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding dma_buf_put(buf); 2313800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingfree_mmap: 2323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding drm_gem_free_mmap_offset(&bo->gem); 2333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingrelease: 2343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding drm_gem_object_release(&bo->gem); 2353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingfree: 2363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding kfree(bo); 2373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return ERR_PTR(err); 2393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 2403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 241de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenvoid tegra_bo_free_object(struct drm_gem_object *gem) 242de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 243de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo = to_tegra_bo(gem); 244de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 2453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (gem->import_attach) { 2463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding dma_buf_unmap_attachment(gem->import_attach, bo->sgt, 2473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding DMA_TO_DEVICE); 2483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding drm_prime_gem_destroy(gem, NULL); 2493800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } else { 2503800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding tegra_bo_destroy(gem->dev, bo); 2513800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 2523800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 2530de23977cfeb5b357ec884ba15417ae118ff9e9bDavid Herrmann drm_gem_free_mmap_offset(gem); 254de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_release(gem); 255de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 256de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen kfree(bo); 257de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 258de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 259de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, 260de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct drm_mode_create_dumb *args) 261de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 262de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 263d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding struct tegra_drm *tegra = drm->dev_private; 264de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo; 265de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 266d1f3e1e0b38d49cbb996dcf0fde5b5205d12a23dThierry Reding min_pitch = round_up(min_pitch, tegra->pitch_align); 267de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (args->pitch < min_pitch) 268de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen args->pitch = min_pitch; 269de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 270de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (args->size < args->pitch * args->height) 271de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen args->size = args->pitch * args->height; 272de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 273773af77fc479fd454c3f6836f86bf63996545cf4Thierry Reding bo = tegra_bo_create_with_handle(file, drm, args->size, 0, 2743be8274341499cfc258eddda29f626d7be10dde5Thierry Reding &args->handle); 275de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (IS_ERR(bo)) 276de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return PTR_ERR(bo); 277de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 278de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return 0; 279de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 280de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 281de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm, 282de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen uint32_t handle, uint64_t *offset) 283de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 284de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct drm_gem_object *gem; 285de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo; 286de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 287de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_lock(&drm->struct_mutex); 288de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 289de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen gem = drm_gem_object_lookup(drm, file, handle); 290de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (!gem) { 291de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen dev_err(drm->dev, "failed to lookup GEM object\n"); 292de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_unlock(&drm->struct_mutex); 293de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return -EINVAL; 294de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen } 295de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 296de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen bo = to_tegra_bo(gem); 297de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 2982bc7b0ca8cc3bdcf61a7d4a99ed55c4ad084a4aeDavid Herrmann *offset = drm_vma_node_offset_addr(&bo->gem.vma_node); 299de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 300de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_object_unreference(gem); 301de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 302de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen mutex_unlock(&drm->struct_mutex); 303de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 304de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return 0; 305de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 306de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 307de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenconst struct vm_operations_struct tegra_bo_vm_ops = { 308de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .open = drm_gem_vm_open, 309de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen .close = drm_gem_vm_close, 310de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen}; 311de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 312de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainenint tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) 313de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen{ 314de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct drm_gem_object *gem; 315de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen struct tegra_bo *bo; 316de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen int ret; 317de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 318de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen ret = drm_gem_mmap(file, vma); 319de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (ret) 320de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return ret; 321de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 322de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen gem = vma->vm_private_data; 323de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen bo = to_tegra_bo(gem); 324de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 325de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen ret = remap_pfn_range(vma, vma->vm_start, bo->paddr >> PAGE_SHIFT, 326de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen vma->vm_end - vma->vm_start, vma->vm_page_prot); 327de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen if (ret) 328de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen drm_gem_vm_close(vma); 329de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen 330de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen return ret; 331de2ba664c30fcdb0f678ab6cbb57e01a0b206085Arto Merilainen} 3323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic struct sg_table * 3343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingtegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, 3353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding enum dma_data_direction dir) 3363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct drm_gem_object *gem = attach->dmabuf->priv; 3383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct tegra_bo *bo = to_tegra_bo(gem); 3393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct sg_table *sgt; 3403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3413800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); 3423800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (!sgt) 3433800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return NULL; 3443800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (sg_alloc_table(sgt, 1, GFP_KERNEL)) { 3463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding kfree(sgt); 3473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return NULL; 3483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 3493800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3503800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding sg_dma_address(sgt->sgl) = bo->paddr; 3513800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding sg_dma_len(sgt->sgl) = gem->size; 3523800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3533800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return sgt; 3543800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3553800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3563800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, 3573800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct sg_table *sgt, 3583800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding enum dma_data_direction dir) 3593800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3603800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding sg_free_table(sgt); 3613800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding kfree(sgt); 3623800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3633800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3643800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_release(struct dma_buf *buf) 3653800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3663800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding drm_gem_dmabuf_release(buf); 3673800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3683800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3693800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void *tegra_gem_prime_kmap_atomic(struct dma_buf *buf, 3703800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding unsigned long page) 3713800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3723800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return NULL; 3733800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3743800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3753800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_kunmap_atomic(struct dma_buf *buf, 3763800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding unsigned long page, 3773800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding void *addr) 3783800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3793800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3803800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3813800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void *tegra_gem_prime_kmap(struct dma_buf *buf, unsigned long page) 3823800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3833800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return NULL; 3843800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3853800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3863800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page, 3873800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding void *addr) 3883800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3893800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3903800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 3913800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma) 3923800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 3933800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return -EINVAL; 3943800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 3953800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 396d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Redingstatic void *tegra_gem_prime_vmap(struct dma_buf *buf) 397d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding{ 398d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding struct drm_gem_object *gem = buf->priv; 399d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding struct tegra_bo *bo = to_tegra_bo(gem); 400d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding 401d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding return bo->vaddr; 402d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding} 403d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding 404d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Redingstatic void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr) 405d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding{ 406d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding} 407d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding 4083800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstatic const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = { 4093800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .map_dma_buf = tegra_gem_prime_map_dma_buf, 4103800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .unmap_dma_buf = tegra_gem_prime_unmap_dma_buf, 4113800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .release = tegra_gem_prime_release, 4123800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .kmap_atomic = tegra_gem_prime_kmap_atomic, 4133800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .kunmap_atomic = tegra_gem_prime_kunmap_atomic, 4143800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .kmap = tegra_gem_prime_kmap, 4153800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .kunmap = tegra_gem_prime_kunmap, 4163800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding .mmap = tegra_gem_prime_mmap, 417d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding .vmap = tegra_gem_prime_vmap, 418d40326f4b9f9617cdfd30f83a2db57d47e9c5bacThierry Reding .vunmap = tegra_gem_prime_vunmap, 4193800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding}; 4203800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4213800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstruct dma_buf *tegra_gem_prime_export(struct drm_device *drm, 4223800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct drm_gem_object *gem, 4233800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding int flags) 4243800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 4253800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return dma_buf_export(gem, &tegra_gem_prime_dmabuf_ops, gem->size, 4263aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst flags, NULL); 4273800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 4283800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4293800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Redingstruct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm, 4303800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct dma_buf *buf) 4313800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding{ 4323800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct tegra_bo *bo; 4333800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4343800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (buf->ops == &tegra_gem_prime_dmabuf_ops) { 4353800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding struct drm_gem_object *gem = buf->priv; 4363800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4373800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (gem->dev == drm) { 4383800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding drm_gem_object_reference(gem); 4393800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return gem; 4403800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 4413800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding } 4423800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4433800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding bo = tegra_bo_import(drm, buf); 4443800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding if (IS_ERR(bo)) 4453800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return ERR_CAST(bo); 4463800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding 4473800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding return &bo->gem; 4483800391db1b22a7f5d5ae92f9c54fa00327d682aThierry Reding} 449