18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2009 Jerome Glisse. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 128c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 158c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 168c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 178c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 188c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 198c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 208c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Authors: Jerome Glisse 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h> 268c2ecf20Sopenharmony_ci#include "radeon_reg.h" 278c2ecf20Sopenharmony_ci#include "radeon.h" 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define RADEON_BENCHMARK_COPY_BLIT 1 308c2ecf20Sopenharmony_ci#define RADEON_BENCHMARK_COPY_DMA 0 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define RADEON_BENCHMARK_ITERATIONS 1024 338c2ecf20Sopenharmony_ci#define RADEON_BENCHMARK_COMMON_MODES_N 17 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, 368c2ecf20Sopenharmony_ci uint64_t saddr, uint64_t daddr, 378c2ecf20Sopenharmony_ci int flag, int n, 388c2ecf20Sopenharmony_ci struct dma_resv *resv) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci unsigned long start_jiffies; 418c2ecf20Sopenharmony_ci unsigned long end_jiffies; 428c2ecf20Sopenharmony_ci struct radeon_fence *fence = NULL; 438c2ecf20Sopenharmony_ci int i, r; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci start_jiffies = jiffies; 468c2ecf20Sopenharmony_ci for (i = 0; i < n; i++) { 478c2ecf20Sopenharmony_ci switch (flag) { 488c2ecf20Sopenharmony_ci case RADEON_BENCHMARK_COPY_DMA: 498c2ecf20Sopenharmony_ci fence = radeon_copy_dma(rdev, saddr, daddr, 508c2ecf20Sopenharmony_ci size / RADEON_GPU_PAGE_SIZE, 518c2ecf20Sopenharmony_ci resv); 528c2ecf20Sopenharmony_ci break; 538c2ecf20Sopenharmony_ci case RADEON_BENCHMARK_COPY_BLIT: 548c2ecf20Sopenharmony_ci fence = radeon_copy_blit(rdev, saddr, daddr, 558c2ecf20Sopenharmony_ci size / RADEON_GPU_PAGE_SIZE, 568c2ecf20Sopenharmony_ci resv); 578c2ecf20Sopenharmony_ci break; 588c2ecf20Sopenharmony_ci default: 598c2ecf20Sopenharmony_ci DRM_ERROR("Unknown copy method\n"); 608c2ecf20Sopenharmony_ci return -EINVAL; 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci if (IS_ERR(fence)) 638c2ecf20Sopenharmony_ci return PTR_ERR(fence); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci r = radeon_fence_wait(fence, false); 668c2ecf20Sopenharmony_ci radeon_fence_unref(&fence); 678c2ecf20Sopenharmony_ci if (r) 688c2ecf20Sopenharmony_ci return r; 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci end_jiffies = jiffies; 718c2ecf20Sopenharmony_ci return jiffies_to_msecs(end_jiffies - start_jiffies); 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic void radeon_benchmark_log_results(int n, unsigned size, 768c2ecf20Sopenharmony_ci unsigned int time, 778c2ecf20Sopenharmony_ci unsigned sdomain, unsigned ddomain, 788c2ecf20Sopenharmony_ci char *kind) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci unsigned int throughput = (n * (size >> 10)) / time; 818c2ecf20Sopenharmony_ci DRM_INFO("radeon: %s %u bo moves of %u kB from" 828c2ecf20Sopenharmony_ci " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n", 838c2ecf20Sopenharmony_ci kind, n, size >> 10, sdomain, ddomain, time, 848c2ecf20Sopenharmony_ci throughput * 8, throughput); 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, 888c2ecf20Sopenharmony_ci unsigned sdomain, unsigned ddomain) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci struct radeon_bo *dobj = NULL; 918c2ecf20Sopenharmony_ci struct radeon_bo *sobj = NULL; 928c2ecf20Sopenharmony_ci uint64_t saddr, daddr; 938c2ecf20Sopenharmony_ci int r, n; 948c2ecf20Sopenharmony_ci int time; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci n = RADEON_BENCHMARK_ITERATIONS; 978c2ecf20Sopenharmony_ci r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, 0, NULL, NULL, &sobj); 988c2ecf20Sopenharmony_ci if (r) { 998c2ecf20Sopenharmony_ci goto out_cleanup; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci r = radeon_bo_reserve(sobj, false); 1028c2ecf20Sopenharmony_ci if (unlikely(r != 0)) 1038c2ecf20Sopenharmony_ci goto out_cleanup; 1048c2ecf20Sopenharmony_ci r = radeon_bo_pin(sobj, sdomain, &saddr); 1058c2ecf20Sopenharmony_ci radeon_bo_unreserve(sobj); 1068c2ecf20Sopenharmony_ci if (r) { 1078c2ecf20Sopenharmony_ci goto out_cleanup; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, 0, NULL, NULL, &dobj); 1108c2ecf20Sopenharmony_ci if (r) { 1118c2ecf20Sopenharmony_ci goto out_cleanup; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci r = radeon_bo_reserve(dobj, false); 1148c2ecf20Sopenharmony_ci if (unlikely(r != 0)) 1158c2ecf20Sopenharmony_ci goto out_cleanup; 1168c2ecf20Sopenharmony_ci r = radeon_bo_pin(dobj, ddomain, &daddr); 1178c2ecf20Sopenharmony_ci radeon_bo_unreserve(dobj); 1188c2ecf20Sopenharmony_ci if (r) { 1198c2ecf20Sopenharmony_ci goto out_cleanup; 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci if (rdev->asic->copy.dma) { 1238c2ecf20Sopenharmony_ci time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 1248c2ecf20Sopenharmony_ci RADEON_BENCHMARK_COPY_DMA, n, 1258c2ecf20Sopenharmony_ci dobj->tbo.base.resv); 1268c2ecf20Sopenharmony_ci if (time < 0) 1278c2ecf20Sopenharmony_ci goto out_cleanup; 1288c2ecf20Sopenharmony_ci if (time > 0) 1298c2ecf20Sopenharmony_ci radeon_benchmark_log_results(n, size, time, 1308c2ecf20Sopenharmony_ci sdomain, ddomain, "dma"); 1318c2ecf20Sopenharmony_ci } 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci if (rdev->asic->copy.blit) { 1348c2ecf20Sopenharmony_ci time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 1358c2ecf20Sopenharmony_ci RADEON_BENCHMARK_COPY_BLIT, n, 1368c2ecf20Sopenharmony_ci dobj->tbo.base.resv); 1378c2ecf20Sopenharmony_ci if (time < 0) 1388c2ecf20Sopenharmony_ci goto out_cleanup; 1398c2ecf20Sopenharmony_ci if (time > 0) 1408c2ecf20Sopenharmony_ci radeon_benchmark_log_results(n, size, time, 1418c2ecf20Sopenharmony_ci sdomain, ddomain, "blit"); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciout_cleanup: 1458c2ecf20Sopenharmony_ci if (sobj) { 1468c2ecf20Sopenharmony_ci r = radeon_bo_reserve(sobj, false); 1478c2ecf20Sopenharmony_ci if (likely(r == 0)) { 1488c2ecf20Sopenharmony_ci radeon_bo_unpin(sobj); 1498c2ecf20Sopenharmony_ci radeon_bo_unreserve(sobj); 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci radeon_bo_unref(&sobj); 1528c2ecf20Sopenharmony_ci } 1538c2ecf20Sopenharmony_ci if (dobj) { 1548c2ecf20Sopenharmony_ci r = radeon_bo_reserve(dobj, false); 1558c2ecf20Sopenharmony_ci if (likely(r == 0)) { 1568c2ecf20Sopenharmony_ci radeon_bo_unpin(dobj); 1578c2ecf20Sopenharmony_ci radeon_bo_unreserve(dobj); 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci radeon_bo_unref(&dobj); 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci if (r) { 1638c2ecf20Sopenharmony_ci DRM_ERROR("Error while benchmarking BO move.\n"); 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_civoid radeon_benchmark(struct radeon_device *rdev, int test_number) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci int i; 1708c2ecf20Sopenharmony_ci int common_modes[RADEON_BENCHMARK_COMMON_MODES_N] = { 1718c2ecf20Sopenharmony_ci 640 * 480 * 4, 1728c2ecf20Sopenharmony_ci 720 * 480 * 4, 1738c2ecf20Sopenharmony_ci 800 * 600 * 4, 1748c2ecf20Sopenharmony_ci 848 * 480 * 4, 1758c2ecf20Sopenharmony_ci 1024 * 768 * 4, 1768c2ecf20Sopenharmony_ci 1152 * 768 * 4, 1778c2ecf20Sopenharmony_ci 1280 * 720 * 4, 1788c2ecf20Sopenharmony_ci 1280 * 800 * 4, 1798c2ecf20Sopenharmony_ci 1280 * 854 * 4, 1808c2ecf20Sopenharmony_ci 1280 * 960 * 4, 1818c2ecf20Sopenharmony_ci 1280 * 1024 * 4, 1828c2ecf20Sopenharmony_ci 1440 * 900 * 4, 1838c2ecf20Sopenharmony_ci 1400 * 1050 * 4, 1848c2ecf20Sopenharmony_ci 1680 * 1050 * 4, 1858c2ecf20Sopenharmony_ci 1600 * 1200 * 4, 1868c2ecf20Sopenharmony_ci 1920 * 1080 * 4, 1878c2ecf20Sopenharmony_ci 1920 * 1200 * 4 1888c2ecf20Sopenharmony_ci }; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci switch (test_number) { 1918c2ecf20Sopenharmony_ci case 1: 1928c2ecf20Sopenharmony_ci /* simple test, VRAM to GTT and GTT to VRAM */ 1938c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT, 1948c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 1958c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 1968c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_GTT); 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci case 2: 1998c2ecf20Sopenharmony_ci /* simple test, VRAM to VRAM */ 2008c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 2018c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 2028c2ecf20Sopenharmony_ci break; 2038c2ecf20Sopenharmony_ci case 3: 2048c2ecf20Sopenharmony_ci /* GTT to VRAM, buffer size sweep, powers of 2 */ 2058c2ecf20Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) 2068c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 2078c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_GTT, 2088c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 2098c2ecf20Sopenharmony_ci break; 2108c2ecf20Sopenharmony_ci case 4: 2118c2ecf20Sopenharmony_ci /* VRAM to GTT, buffer size sweep, powers of 2 */ 2128c2ecf20Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) 2138c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 2148c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 2158c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_GTT); 2168c2ecf20Sopenharmony_ci break; 2178c2ecf20Sopenharmony_ci case 5: 2188c2ecf20Sopenharmony_ci /* VRAM to VRAM, buffer size sweep, powers of 2 */ 2198c2ecf20Sopenharmony_ci for (i = 1; i <= 16384; i <<= 1) 2208c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 2218c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 2228c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 2238c2ecf20Sopenharmony_ci break; 2248c2ecf20Sopenharmony_ci case 6: 2258c2ecf20Sopenharmony_ci /* GTT to VRAM, buffer size sweep, common modes */ 2268c2ecf20Sopenharmony_ci for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 2278c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, common_modes[i], 2288c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_GTT, 2298c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 2308c2ecf20Sopenharmony_ci break; 2318c2ecf20Sopenharmony_ci case 7: 2328c2ecf20Sopenharmony_ci /* VRAM to GTT, buffer size sweep, common modes */ 2338c2ecf20Sopenharmony_ci for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 2348c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, common_modes[i], 2358c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 2368c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_GTT); 2378c2ecf20Sopenharmony_ci break; 2388c2ecf20Sopenharmony_ci case 8: 2398c2ecf20Sopenharmony_ci /* VRAM to VRAM, buffer size sweep, common modes */ 2408c2ecf20Sopenharmony_ci for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 2418c2ecf20Sopenharmony_ci radeon_benchmark_move(rdev, common_modes[i], 2428c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 2438c2ecf20Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM); 2448c2ecf20Sopenharmony_ci break; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci default: 2478c2ecf20Sopenharmony_ci DRM_ERROR("Unknown benchmark\n"); 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci} 250