2009-06-05 14:42:42 +02:00
/*
* Copyright 2009 Jerome Glisse .
*
* 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 .
*
* Authors : Jerome Glisse
*/
# include <drm/drmP.h>
# include <drm/radeon_drm.h>
# include "radeon_reg.h"
# include "radeon.h"
2011-10-12 23:29:38 -04:00
# define RADEON_BENCHMARK_COPY_BLIT 1
# define RADEON_BENCHMARK_COPY_DMA 0
# define RADEON_BENCHMARK_ITERATIONS 1024
2011-10-12 23:29:39 -04:00
# define RADEON_BENCHMARK_COMMON_MODES_N 17
2011-10-12 23:29:38 -04:00
static int radeon_benchmark_do_move ( struct radeon_device * rdev , unsigned size ,
uint64_t saddr , uint64_t daddr ,
2015-01-30 00:38:43 -05:00
int flag , int n ,
struct reservation_object * resv )
2011-10-12 23:29:38 -04:00
{
unsigned long start_jiffies ;
unsigned long end_jiffies ;
struct radeon_fence * fence = NULL ;
int i , r ;
start_jiffies = jiffies ;
for ( i = 0 ; i < n ; i + + ) {
switch ( flag ) {
case RADEON_BENCHMARK_COPY_DMA :
2014-09-04 20:01:53 +02:00
fence = radeon_copy_dma ( rdev , saddr , daddr ,
size / RADEON_GPU_PAGE_SIZE ,
2015-01-30 00:38:43 -05:00
resv ) ;
2011-10-12 23:29:38 -04:00
break ;
case RADEON_BENCHMARK_COPY_BLIT :
2014-09-04 20:01:53 +02:00
fence = radeon_copy_blit ( rdev , saddr , daddr ,
size / RADEON_GPU_PAGE_SIZE ,
2015-01-30 00:38:43 -05:00
resv ) ;
2011-10-12 23:29:38 -04:00
break ;
default :
DRM_ERROR ( " Unknown copy method \n " ) ;
2014-09-04 20:01:53 +02:00
return - EINVAL ;
2011-10-12 23:29:38 -04:00
}
2014-09-04 20:01:53 +02:00
if ( IS_ERR ( fence ) )
return PTR_ERR ( fence ) ;
2011-10-12 23:29:38 -04:00
r = radeon_fence_wait ( fence , false ) ;
radeon_fence_unref ( & fence ) ;
2014-09-04 20:01:53 +02:00
if ( r )
return r ;
2011-10-12 23:29:38 -04:00
}
end_jiffies = jiffies ;
2014-09-04 20:01:53 +02:00
return jiffies_to_msecs ( end_jiffies - start_jiffies ) ;
2011-10-12 23:29:38 -04:00
}
static void radeon_benchmark_log_results ( int n , unsigned size ,
unsigned int time ,
unsigned sdomain , unsigned ddomain ,
char * kind )
{
unsigned int throughput = ( n * ( size > > 10 ) ) / time ;
DRM_INFO ( " radeon: %s %u bo moves of %u kB from "
" %d to %d in %u ms, throughput: %u Mb/s or %u MB/s \n " ,
kind , n , size > > 10 , sdomain , ddomain , time ,
throughput * 8 , throughput ) ;
}
static void radeon_benchmark_move ( struct radeon_device * rdev , unsigned size ,
unsigned sdomain , unsigned ddomain )
2009-06-05 14:42:42 +02:00
{
2009-11-20 14:29:23 +01:00
struct radeon_bo * dobj = NULL ;
struct radeon_bo * sobj = NULL ;
2009-06-05 14:42:42 +02:00
uint64_t saddr , daddr ;
2011-10-12 23:29:38 -04:00
int r , n ;
2011-10-29 10:21:28 +03:00
int time ;
2009-06-05 14:42:42 +02:00
2011-10-12 23:29:38 -04:00
n = RADEON_BENCHMARK_ITERATIONS ;
2014-09-18 14:11:56 +02:00
r = radeon_bo_create ( rdev , size , PAGE_SIZE , true , sdomain , 0 , NULL , NULL , & sobj ) ;
2009-06-05 14:42:42 +02:00
if ( r ) {
goto out_cleanup ;
}
2009-11-20 14:29:23 +01:00
r = radeon_bo_reserve ( sobj , false ) ;
if ( unlikely ( r ! = 0 ) )
goto out_cleanup ;
r = radeon_bo_pin ( sobj , sdomain , & saddr ) ;
radeon_bo_unreserve ( sobj ) ;
2009-06-05 14:42:42 +02:00
if ( r ) {
goto out_cleanup ;
}
2014-09-18 14:11:56 +02:00
r = radeon_bo_create ( rdev , size , PAGE_SIZE , true , ddomain , 0 , NULL , NULL , & dobj ) ;
2009-06-05 14:42:42 +02:00
if ( r ) {
goto out_cleanup ;
}
2009-11-20 14:29:23 +01:00
r = radeon_bo_reserve ( dobj , false ) ;
if ( unlikely ( r ! = 0 ) )
goto out_cleanup ;
r = radeon_bo_pin ( dobj , ddomain , & daddr ) ;
radeon_bo_unreserve ( dobj ) ;
2009-06-05 14:42:42 +02:00
if ( r ) {
goto out_cleanup ;
}
2010-02-11 00:10:33 +02:00
2013-03-12 12:55:56 -04:00
if ( rdev - > asic - > copy . dma ) {
2011-10-12 23:29:38 -04:00
time = radeon_benchmark_do_move ( rdev , size , saddr , daddr ,
2015-01-30 00:38:43 -05:00
RADEON_BENCHMARK_COPY_DMA , n ,
dobj - > tbo . resv ) ;
2011-10-12 23:29:38 -04:00
if ( time < 0 )
2009-06-05 14:42:42 +02:00
goto out_cleanup ;
2011-10-12 23:29:38 -04:00
if ( time > 0 )
radeon_benchmark_log_results ( n , size , time ,
sdomain , ddomain , " dma " ) ;
2009-06-05 14:42:42 +02:00
}
2011-10-12 23:29:38 -04:00
2013-03-12 12:53:13 -04:00
if ( rdev - > asic - > copy . blit ) {
time = radeon_benchmark_do_move ( rdev , size , saddr , daddr ,
2015-01-30 00:38:43 -05:00
RADEON_BENCHMARK_COPY_BLIT , n ,
dobj - > tbo . resv ) ;
2013-03-12 12:53:13 -04:00
if ( time < 0 )
goto out_cleanup ;
if ( time > 0 )
radeon_benchmark_log_results ( n , size , time ,
sdomain , ddomain , " blit " ) ;
}
2011-10-12 23:29:38 -04:00
2009-06-05 14:42:42 +02:00
out_cleanup :
if ( sobj ) {
2009-11-20 14:29:23 +01:00
r = radeon_bo_reserve ( sobj , false ) ;
if ( likely ( r = = 0 ) ) {
radeon_bo_unpin ( sobj ) ;
radeon_bo_unreserve ( sobj ) ;
}
radeon_bo_unref ( & sobj ) ;
2009-06-05 14:42:42 +02:00
}
if ( dobj ) {
2009-11-20 14:29:23 +01:00
r = radeon_bo_reserve ( dobj , false ) ;
if ( likely ( r = = 0 ) ) {
radeon_bo_unpin ( dobj ) ;
radeon_bo_unreserve ( dobj ) ;
}
radeon_bo_unref ( & dobj ) ;
2009-06-05 14:42:42 +02:00
}
2011-10-12 23:29:38 -04:00
2009-06-05 14:42:42 +02:00
if ( r ) {
2011-10-12 23:29:38 -04:00
DRM_ERROR ( " Error while benchmarking BO move. \n " ) ;
2009-06-05 14:42:42 +02:00
}
}
2011-10-12 23:29:39 -04:00
void radeon_benchmark ( struct radeon_device * rdev , int test_number )
2009-06-05 14:42:42 +02:00
{
2011-10-12 23:29:39 -04:00
int i ;
int common_modes [ RADEON_BENCHMARK_COMMON_MODES_N ] = {
640 * 480 * 4 ,
720 * 480 * 4 ,
800 * 600 * 4 ,
848 * 480 * 4 ,
1024 * 768 * 4 ,
1152 * 768 * 4 ,
1280 * 720 * 4 ,
1280 * 800 * 4 ,
1280 * 854 * 4 ,
1280 * 960 * 4 ,
1280 * 1024 * 4 ,
1440 * 900 * 4 ,
1400 * 1050 * 4 ,
1680 * 1050 * 4 ,
1600 * 1200 * 4 ,
1920 * 1080 * 4 ,
1920 * 1200 * 4
} ;
switch ( test_number ) {
case 1 :
/* simple test, VRAM to GTT and GTT to VRAM */
radeon_benchmark_move ( rdev , 1024 * 1024 , RADEON_GEM_DOMAIN_GTT ,
RADEON_GEM_DOMAIN_VRAM ) ;
radeon_benchmark_move ( rdev , 1024 * 1024 , RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_GTT ) ;
break ;
case 2 :
/* simple test, VRAM to VRAM */
radeon_benchmark_move ( rdev , 1024 * 1024 , RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_VRAM ) ;
break ;
case 3 :
/* GTT to VRAM, buffer size sweep, powers of 2 */
2012-01-31 09:35:25 -05:00
for ( i = 1 ; i < = 16384 ; i < < = 1 )
radeon_benchmark_move ( rdev , i * RADEON_GPU_PAGE_SIZE ,
2011-10-12 23:29:39 -04:00
RADEON_GEM_DOMAIN_GTT ,
RADEON_GEM_DOMAIN_VRAM ) ;
break ;
case 4 :
/* VRAM to GTT, buffer size sweep, powers of 2 */
2012-01-31 09:35:25 -05:00
for ( i = 1 ; i < = 16384 ; i < < = 1 )
radeon_benchmark_move ( rdev , i * RADEON_GPU_PAGE_SIZE ,
2011-10-12 23:29:39 -04:00
RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_GTT ) ;
break ;
case 5 :
/* VRAM to VRAM, buffer size sweep, powers of 2 */
2012-01-31 09:35:25 -05:00
for ( i = 1 ; i < = 16384 ; i < < = 1 )
radeon_benchmark_move ( rdev , i * RADEON_GPU_PAGE_SIZE ,
2011-10-12 23:29:39 -04:00
RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_VRAM ) ;
break ;
case 6 :
/* GTT to VRAM, buffer size sweep, common modes */
2011-12-07 10:18:18 +08:00
for ( i = 0 ; i < RADEON_BENCHMARK_COMMON_MODES_N ; i + + )
2011-10-12 23:29:39 -04:00
radeon_benchmark_move ( rdev , common_modes [ i ] ,
RADEON_GEM_DOMAIN_GTT ,
RADEON_GEM_DOMAIN_VRAM ) ;
break ;
case 7 :
/* VRAM to GTT, buffer size sweep, common modes */
2011-12-07 10:18:18 +08:00
for ( i = 0 ; i < RADEON_BENCHMARK_COMMON_MODES_N ; i + + )
2011-10-12 23:29:39 -04:00
radeon_benchmark_move ( rdev , common_modes [ i ] ,
RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_GTT ) ;
break ;
case 8 :
/* VRAM to VRAM, buffer size sweep, common modes */
2011-12-07 10:18:18 +08:00
for ( i = 0 ; i < RADEON_BENCHMARK_COMMON_MODES_N ; i + + )
2011-10-12 23:29:39 -04:00
radeon_benchmark_move ( rdev , common_modes [ i ] ,
RADEON_GEM_DOMAIN_VRAM ,
RADEON_GEM_DOMAIN_VRAM ) ;
break ;
default :
DRM_ERROR ( " Unknown benchmark \n " ) ;
}
2009-06-05 14:42:42 +02:00
}