2012-05-11 02:33:13 +04:00
/*
* Copyright 2012 Advanced Micro Devices , Inc .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*
* based on nouveau_prime . c
*
* Authors : Alex Deucher
*/
2012-10-02 21:01:07 +04:00
# include <drm/drmP.h>
2012-05-11 02:33:13 +04:00
# include "radeon.h"
2012-10-02 21:01:07 +04:00
# include <drm/radeon_drm.h>
2012-05-11 02:33:13 +04:00
2013-01-16 00:47:44 +04:00
struct sg_table * radeon_gem_prime_get_sg_table ( struct drm_gem_object * obj )
2012-05-11 02:33:13 +04:00
{
2013-01-16 00:47:44 +04:00
struct radeon_bo * bo = gem_to_radeon_bo ( obj ) ;
2012-05-11 02:33:13 +04:00
int npages = bo - > tbo . num_pages ;
2013-01-16 00:47:44 +04:00
return drm_prime_pages_to_sg ( bo - > tbo . ttm - > pages , npages ) ;
2012-05-11 02:33:13 +04:00
}
2013-01-16 00:47:44 +04:00
void * radeon_gem_prime_vmap ( struct drm_gem_object * obj )
2012-05-29 18:12:24 +04:00
{
2013-01-16 00:47:44 +04:00
struct radeon_bo * bo = gem_to_radeon_bo ( obj ) ;
2012-05-31 16:52:53 +04:00
int ret ;
ret = ttm_bo_kmap ( & bo - > tbo , 0 , bo - > tbo . num_pages ,
& bo - > dma_buf_vmap ) ;
2013-01-16 00:47:44 +04:00
if ( ret )
2012-05-31 16:52:53 +04:00
return ERR_PTR ( ret ) ;
2013-01-16 00:47:44 +04:00
2012-05-31 16:52:53 +04:00
return bo - > dma_buf_vmap . virtual ;
}
2013-01-16 00:47:44 +04:00
void radeon_gem_prime_vunmap ( struct drm_gem_object * obj , void * vaddr )
2012-05-31 16:52:53 +04:00
{
2013-01-16 00:47:44 +04:00
struct radeon_bo * bo = gem_to_radeon_bo ( obj ) ;
2012-05-31 16:52:53 +04:00
2013-01-16 00:47:44 +04:00
ttm_bo_kunmap ( & bo - > dma_buf_vmap ) ;
2012-05-31 16:52:53 +04:00
}
2013-01-16 00:47:44 +04:00
struct drm_gem_object * radeon_gem_prime_import_sg_table ( struct drm_device * dev ,
size_t size ,
struct sg_table * sg )
2012-05-11 02:33:13 +04:00
{
struct radeon_device * rdev = dev - > dev_private ;
struct radeon_bo * bo ;
int ret ;
ret = radeon_bo_create ( rdev , size , PAGE_SIZE , false ,
2013-01-16 00:47:44 +04:00
RADEON_GEM_DOMAIN_GTT , sg , & bo ) ;
2012-05-11 02:33:13 +04:00
if ( ret )
2013-01-16 00:47:44 +04:00
return ERR_PTR ( ret ) ;
2012-05-11 02:33:13 +04:00
bo - > gem_base . driver_private = bo ;
mutex_lock ( & rdev - > gem . mutex ) ;
list_add_tail ( & bo - > list , & rdev - > gem . objects ) ;
mutex_unlock ( & rdev - > gem . mutex ) ;
2013-01-16 00:47:44 +04:00
return & bo - > gem_base ;
2012-05-11 02:33:13 +04:00
}
2013-01-16 00:47:44 +04:00
int radeon_gem_prime_pin ( struct drm_gem_object * obj )
2012-05-11 02:33:13 +04:00
{
struct radeon_bo * bo = gem_to_radeon_bo ( obj ) ;
int ret = 0 ;
2012-06-12 19:10:39 +04:00
ret = radeon_bo_reserve ( bo , false ) ;
if ( unlikely ( ret ! = 0 ) )
2013-01-16 00:47:44 +04:00
return ret ;
2012-06-12 19:10:39 +04:00
2012-05-11 02:33:13 +04:00
/* pin buffer into GTT */
ret = radeon_bo_pin ( bo , RADEON_GEM_DOMAIN_GTT , NULL ) ;
2012-06-12 19:10:39 +04:00
radeon_bo_unreserve ( bo ) ;
2013-06-27 15:38:18 +04:00
return ret ;
}
void radeon_gem_prime_unpin ( struct drm_gem_object * obj )
{
struct radeon_bo * bo = gem_to_radeon_bo ( obj ) ;
int ret = 0 ;
2012-05-11 02:33:13 +04:00
2013-06-27 15:38:18 +04:00
ret = radeon_bo_reserve ( bo , false ) ;
if ( unlikely ( ret ! = 0 ) )
return ;
radeon_bo_unpin ( bo ) ;
radeon_bo_unreserve ( bo ) ;
2012-05-11 02:33:13 +04:00
}