140f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher/* 240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * Copyright 2012 Advanced Micro Devices, Inc. 340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * 440f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * Permission is hereby granted, free of charge, to any person obtaining a 540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * copy of this software and associated documentation files (the "Software"), 640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * to deal in the Software without restriction, including without limitation 740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * the rights to use, copy, modify, merge, publish, distribute, sublicense, 840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * and/or sell copies of the Software, and to permit persons to whom the 940f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * Software is furnished to do so, subject to the following conditions: 1040f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * 1140f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * The above copyright notice and this permission notice shall be included in 1240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * all copies or substantial portions of the Software. 1340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * 1440f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1940f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2040f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * OTHER DEALINGS IN THE SOFTWARE. 2140f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * 2240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * based on nouveau_prime.c 2340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * 2440f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher * Authors: Alex Deucher 2540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher */ 26760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/drmP.h> 2740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 2840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher#include "radeon.h" 29760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/radeon_drm.h> 30b5e9c1a25fcf8a0d664606251a53b5caa6a19d08Maarten Lankhorst#include <linux/dma-buf.h> 3140f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 321e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattnerstruct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj) 3340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher{ 341e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner struct radeon_bo *bo = gem_to_radeon_bo(obj); 3540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher int npages = bo->tbo.num_pages; 3640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 371e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); 3840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher} 3940f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 401e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattnervoid *radeon_gem_prime_vmap(struct drm_gem_object *obj) 41946c7491b37704016cdbba60915d1de2c79c3b57Dave Airlie{ 421e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner struct radeon_bo *bo = gem_to_radeon_bo(obj); 4363bc620b45af8c743ac291c8725933278c712692Dave Airlie int ret; 4463bc620b45af8c743ac291c8725933278c712692Dave Airlie 4563bc620b45af8c743ac291c8725933278c712692Dave Airlie ret = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, 4663bc620b45af8c743ac291c8725933278c712692Dave Airlie &bo->dma_buf_vmap); 471e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner if (ret) 4863bc620b45af8c743ac291c8725933278c712692Dave Airlie return ERR_PTR(ret); 491e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner 5063bc620b45af8c743ac291c8725933278c712692Dave Airlie return bo->dma_buf_vmap.virtual; 5163bc620b45af8c743ac291c8725933278c712692Dave Airlie} 5263bc620b45af8c743ac291c8725933278c712692Dave Airlie 531e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattnervoid radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) 5463bc620b45af8c743ac291c8725933278c712692Dave Airlie{ 551e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner struct radeon_bo *bo = gem_to_radeon_bo(obj); 5663bc620b45af8c743ac291c8725933278c712692Dave Airlie 571e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner ttm_bo_kunmap(&bo->dma_buf_vmap); 5863bc620b45af8c743ac291c8725933278c712692Dave Airlie} 591e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner 601e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattnerstruct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev, 61b5e9c1a25fcf8a0d664606251a53b5caa6a19d08Maarten Lankhorst struct dma_buf_attachment *attach, 621e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner struct sg_table *sg) 6340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher{ 64831b6966a60fe72d85ae3576056b4e4e0775b112Maarten Lankhorst struct reservation_object *resv = attach->dmabuf->resv; 6540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher struct radeon_device *rdev = dev->dev_private; 6640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher struct radeon_bo *bo; 6740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher int ret; 6840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 69831b6966a60fe72d85ae3576056b4e4e0775b112Maarten Lankhorst ww_mutex_lock(&resv->lock, NULL); 70b5e9c1a25fcf8a0d664606251a53b5caa6a19d08Maarten Lankhorst ret = radeon_bo_create(rdev, attach->dmabuf->size, PAGE_SIZE, false, 71831b6966a60fe72d85ae3576056b4e4e0775b112Maarten Lankhorst RADEON_GEM_DOMAIN_GTT, 0, sg, resv, &bo); 72831b6966a60fe72d85ae3576056b4e4e0775b112Maarten Lankhorst ww_mutex_unlock(&resv->lock); 7340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher if (ret) 741e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner return ERR_PTR(ret); 7540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 7640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher mutex_lock(&rdev->gem.mutex); 7740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher list_add_tail(&bo->list, &rdev->gem.objects); 7840f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher mutex_unlock(&rdev->gem.mutex); 7940f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 801e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner return &bo->gem_base; 8140f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher} 8240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 831e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattnerint radeon_gem_prime_pin(struct drm_gem_object *obj) 8440f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher{ 8540f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher struct radeon_bo *bo = gem_to_radeon_bo(obj); 8640f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher int ret = 0; 8740f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 88489797d510dfbce15120492d7ef6f956928b99f2Dave Airlie ret = radeon_bo_reserve(bo, false); 89489797d510dfbce15120492d7ef6f956928b99f2Dave Airlie if (unlikely(ret != 0)) 901e6d17a5df848cf8e483b689c6295776e9d6d997Aaron Plattner return ret; 91489797d510dfbce15120492d7ef6f956928b99f2Dave Airlie 9240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher /* pin buffer into GTT */ 9340f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); 94489797d510dfbce15120492d7ef6f956928b99f2Dave Airlie radeon_bo_unreserve(bo); 95280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst return ret; 96280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst} 97280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst 98280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorstvoid radeon_gem_prime_unpin(struct drm_gem_object *obj) 99280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst{ 100280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst struct radeon_bo *bo = gem_to_radeon_bo(obj); 101280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst int ret = 0; 10240f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher 103280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst ret = radeon_bo_reserve(bo, false); 104280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst if (unlikely(ret != 0)) 105280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst return; 106280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst 107280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst radeon_bo_unpin(bo); 108280cf211867539a7b6912d3a3573ef692ae66b61Maarten Lankhorst radeon_bo_unreserve(bo); 10940f5cf996991577ec65d36cd3599cca7ec5d87d3Alex Deucher} 1103aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst 1113aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst 1123aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorststruct reservation_object *radeon_gem_prime_res_obj(struct drm_gem_object *obj) 1133aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst{ 1143aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst struct radeon_bo *bo = gem_to_radeon_bo(obj); 1153aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst 1163aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst return bo->tbo.resv; 1173aac4502fd3f80dcf7e65dbf6edd8676893c1f46Maarten Lankhorst} 118484048db6b4890bc433aac7f5e32fdcf1b2b4786Dave Airlie 119f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian Königstruct dma_buf *radeon_gem_prime_export(struct drm_device *dev, 120f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König struct drm_gem_object *gobj, 121f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König int flags) 122f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König{ 123f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König struct radeon_bo *bo = gem_to_radeon_bo(gobj); 124f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) 125f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König return ERR_PTR(-EPERM); 126f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König return drm_gem_prime_export(dev, gobj, flags); 127f72a113a71ab08c4df8a5f80ab2f8a140feb81f6Christian König} 128