1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2009 Jerome Glisse. 3254885Sdumbbell * 4254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 5254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 6254885Sdumbbell * to deal in the Software without restriction, including without limitation 7254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 9254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 10254885Sdumbbell * 11254885Sdumbbell * The above copyright notice and this permission notice shall be included in 12254885Sdumbbell * all copies or substantial portions of the Software. 13254885Sdumbbell * 14254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 21254885Sdumbbell * 22254885Sdumbbell * Authors: Jerome Glisse 23254885Sdumbbell */ 24254885Sdumbbell 25254885Sdumbbell#include <sys/cdefs.h> 26254885Sdumbbell__FBSDID("$FreeBSD: releng/10.2/sys/dev/drm2/radeon/radeon_benchmark.c 282199 2015-04-28 19:35:05Z dumbbell $"); 27254885Sdumbbell 28254885Sdumbbell#include <dev/drm2/drmP.h> 29254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 30254885Sdumbbell#include "radeon_reg.h" 31254885Sdumbbell#include "radeon.h" 32254885Sdumbbell 33254885Sdumbbell#define RADEON_BENCHMARK_COPY_BLIT 1 34254885Sdumbbell#define RADEON_BENCHMARK_COPY_DMA 0 35254885Sdumbbell 36254885Sdumbbell#define RADEON_BENCHMARK_ITERATIONS 1024 37254885Sdumbbell#define RADEON_BENCHMARK_COMMON_MODES_N 17 38254885Sdumbbell 39254885Sdumbbellstatic int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, 40254885Sdumbbell uint64_t saddr, uint64_t daddr, 41254885Sdumbbell int flag, int n) 42254885Sdumbbell{ 43254885Sdumbbell unsigned long start_jiffies; 44254885Sdumbbell unsigned long end_jiffies; 45254885Sdumbbell struct radeon_fence *fence = NULL; 46254885Sdumbbell int i, r; 47254885Sdumbbell 48254885Sdumbbell start_jiffies = jiffies; 49254885Sdumbbell for (i = 0; i < n; i++) { 50254885Sdumbbell switch (flag) { 51254885Sdumbbell case RADEON_BENCHMARK_COPY_DMA: 52254885Sdumbbell r = radeon_copy_dma(rdev, saddr, daddr, 53254885Sdumbbell size / RADEON_GPU_PAGE_SIZE, 54254885Sdumbbell &fence); 55254885Sdumbbell break; 56254885Sdumbbell case RADEON_BENCHMARK_COPY_BLIT: 57254885Sdumbbell r = radeon_copy_blit(rdev, saddr, daddr, 58254885Sdumbbell size / RADEON_GPU_PAGE_SIZE, 59254885Sdumbbell &fence); 60254885Sdumbbell break; 61254885Sdumbbell default: 62254885Sdumbbell DRM_ERROR("Unknown copy method\n"); 63254885Sdumbbell r = -EINVAL; 64254885Sdumbbell } 65254885Sdumbbell if (r) 66254885Sdumbbell goto exit_do_move; 67254885Sdumbbell r = radeon_fence_wait(fence, false); 68254885Sdumbbell if (r) 69254885Sdumbbell goto exit_do_move; 70254885Sdumbbell radeon_fence_unref(&fence); 71254885Sdumbbell } 72254885Sdumbbell end_jiffies = jiffies; 73254885Sdumbbell r = jiffies_to_msecs(end_jiffies - start_jiffies); 74254885Sdumbbell 75254885Sdumbbellexit_do_move: 76254885Sdumbbell if (fence) 77254885Sdumbbell radeon_fence_unref(&fence); 78254885Sdumbbell return r; 79254885Sdumbbell} 80254885Sdumbbell 81254885Sdumbbell 82254885Sdumbbellstatic void radeon_benchmark_log_results(int n, unsigned size, 83254885Sdumbbell unsigned int time, 84254885Sdumbbell unsigned sdomain, unsigned ddomain, 85254885Sdumbbell char *kind) 86254885Sdumbbell{ 87254885Sdumbbell unsigned int throughput = (n * (size >> 10)) / time; 88254885Sdumbbell DRM_INFO("radeon: %s %u bo moves of %u kB from" 89254885Sdumbbell " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n", 90254885Sdumbbell kind, n, size >> 10, sdomain, ddomain, time, 91254885Sdumbbell throughput * 8, throughput); 92254885Sdumbbell} 93254885Sdumbbell 94254885Sdumbbellstatic void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, 95254885Sdumbbell unsigned sdomain, unsigned ddomain) 96254885Sdumbbell{ 97254885Sdumbbell struct radeon_bo *dobj = NULL; 98254885Sdumbbell struct radeon_bo *sobj = NULL; 99254885Sdumbbell uint64_t saddr, daddr; 100254885Sdumbbell int r, n; 101254885Sdumbbell int time; 102254885Sdumbbell 103254885Sdumbbell n = RADEON_BENCHMARK_ITERATIONS; 104254885Sdumbbell r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, NULL, &sobj); 105254885Sdumbbell if (r) { 106254885Sdumbbell goto out_cleanup; 107254885Sdumbbell } 108254885Sdumbbell r = radeon_bo_reserve(sobj, false); 109254885Sdumbbell if (unlikely(r != 0)) 110254885Sdumbbell goto out_cleanup; 111254885Sdumbbell r = radeon_bo_pin(sobj, sdomain, &saddr); 112254885Sdumbbell radeon_bo_unreserve(sobj); 113254885Sdumbbell if (r) { 114254885Sdumbbell goto out_cleanup; 115254885Sdumbbell } 116254885Sdumbbell r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, NULL, &dobj); 117254885Sdumbbell if (r) { 118254885Sdumbbell goto out_cleanup; 119254885Sdumbbell } 120254885Sdumbbell r = radeon_bo_reserve(dobj, false); 121254885Sdumbbell if (unlikely(r != 0)) 122254885Sdumbbell goto out_cleanup; 123254885Sdumbbell r = radeon_bo_pin(dobj, ddomain, &daddr); 124254885Sdumbbell radeon_bo_unreserve(dobj); 125254885Sdumbbell if (r) { 126254885Sdumbbell goto out_cleanup; 127254885Sdumbbell } 128254885Sdumbbell 129254885Sdumbbell /* r100 doesn't have dma engine so skip the test */ 130254885Sdumbbell /* also, VRAM-to-VRAM test doesn't make much sense for DMA */ 131254885Sdumbbell /* skip it as well if domains are the same */ 132254885Sdumbbell if ((rdev->asic->copy.dma) && (sdomain != ddomain)) { 133254885Sdumbbell time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 134254885Sdumbbell RADEON_BENCHMARK_COPY_DMA, n); 135254885Sdumbbell if (time < 0) 136254885Sdumbbell goto out_cleanup; 137254885Sdumbbell if (time > 0) 138254885Sdumbbell radeon_benchmark_log_results(n, size, time, 139254885Sdumbbell sdomain, ddomain, "dma"); 140254885Sdumbbell } 141254885Sdumbbell 142282199Sdumbbell if (rdev->asic->copy.blit) { 143282199Sdumbbell time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 144282199Sdumbbell RADEON_BENCHMARK_COPY_BLIT, n); 145282199Sdumbbell if (time < 0) 146282199Sdumbbell goto out_cleanup; 147282199Sdumbbell if (time > 0) 148282199Sdumbbell radeon_benchmark_log_results(n, size, time, 149282199Sdumbbell sdomain, ddomain, "blit"); 150282199Sdumbbell } 151254885Sdumbbell 152254885Sdumbbellout_cleanup: 153254885Sdumbbell if (sobj) { 154254885Sdumbbell r = radeon_bo_reserve(sobj, false); 155254885Sdumbbell if (likely(r == 0)) { 156254885Sdumbbell radeon_bo_unpin(sobj); 157254885Sdumbbell radeon_bo_unreserve(sobj); 158254885Sdumbbell } 159254885Sdumbbell radeon_bo_unref(&sobj); 160254885Sdumbbell } 161254885Sdumbbell if (dobj) { 162254885Sdumbbell r = radeon_bo_reserve(dobj, false); 163254885Sdumbbell if (likely(r == 0)) { 164254885Sdumbbell radeon_bo_unpin(dobj); 165254885Sdumbbell radeon_bo_unreserve(dobj); 166254885Sdumbbell } 167254885Sdumbbell radeon_bo_unref(&dobj); 168254885Sdumbbell } 169254885Sdumbbell 170254885Sdumbbell if (r) { 171254885Sdumbbell DRM_ERROR("Error while benchmarking BO move.\n"); 172254885Sdumbbell } 173254885Sdumbbell} 174254885Sdumbbell 175254885Sdumbbellvoid radeon_benchmark(struct radeon_device *rdev, int test_number) 176254885Sdumbbell{ 177254885Sdumbbell int i; 178254885Sdumbbell int common_modes[RADEON_BENCHMARK_COMMON_MODES_N] = { 179254885Sdumbbell 640 * 480 * 4, 180254885Sdumbbell 720 * 480 * 4, 181254885Sdumbbell 800 * 600 * 4, 182254885Sdumbbell 848 * 480 * 4, 183254885Sdumbbell 1024 * 768 * 4, 184254885Sdumbbell 1152 * 768 * 4, 185254885Sdumbbell 1280 * 720 * 4, 186254885Sdumbbell 1280 * 800 * 4, 187254885Sdumbbell 1280 * 854 * 4, 188254885Sdumbbell 1280 * 960 * 4, 189254885Sdumbbell 1280 * 1024 * 4, 190254885Sdumbbell 1440 * 900 * 4, 191254885Sdumbbell 1400 * 1050 * 4, 192254885Sdumbbell 1680 * 1050 * 4, 193254885Sdumbbell 1600 * 1200 * 4, 194254885Sdumbbell 1920 * 1080 * 4, 195254885Sdumbbell 1920 * 1200 * 4 196254885Sdumbbell }; 197254885Sdumbbell 198254885Sdumbbell switch (test_number) { 199254885Sdumbbell case 1: 200254885Sdumbbell /* simple test, VRAM to GTT and GTT to VRAM */ 201254885Sdumbbell radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT, 202254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 203254885Sdumbbell radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 204254885Sdumbbell RADEON_GEM_DOMAIN_GTT); 205254885Sdumbbell break; 206254885Sdumbbell case 2: 207254885Sdumbbell /* simple test, VRAM to VRAM */ 208254885Sdumbbell radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 209254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 210254885Sdumbbell break; 211254885Sdumbbell case 3: 212254885Sdumbbell /* GTT to VRAM, buffer size sweep, powers of 2 */ 213254885Sdumbbell for (i = 1; i <= 16384; i <<= 1) 214254885Sdumbbell radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 215254885Sdumbbell RADEON_GEM_DOMAIN_GTT, 216254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 217254885Sdumbbell break; 218254885Sdumbbell case 4: 219254885Sdumbbell /* VRAM to GTT, buffer size sweep, powers of 2 */ 220254885Sdumbbell for (i = 1; i <= 16384; i <<= 1) 221254885Sdumbbell radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 222254885Sdumbbell RADEON_GEM_DOMAIN_VRAM, 223254885Sdumbbell RADEON_GEM_DOMAIN_GTT); 224254885Sdumbbell break; 225254885Sdumbbell case 5: 226254885Sdumbbell /* VRAM to VRAM, buffer size sweep, powers of 2 */ 227254885Sdumbbell for (i = 1; i <= 16384; i <<= 1) 228254885Sdumbbell radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 229254885Sdumbbell RADEON_GEM_DOMAIN_VRAM, 230254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 231254885Sdumbbell break; 232254885Sdumbbell case 6: 233254885Sdumbbell /* GTT to VRAM, buffer size sweep, common modes */ 234254885Sdumbbell for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 235254885Sdumbbell radeon_benchmark_move(rdev, common_modes[i], 236254885Sdumbbell RADEON_GEM_DOMAIN_GTT, 237254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 238254885Sdumbbell break; 239254885Sdumbbell case 7: 240254885Sdumbbell /* VRAM to GTT, buffer size sweep, common modes */ 241254885Sdumbbell for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 242254885Sdumbbell radeon_benchmark_move(rdev, common_modes[i], 243254885Sdumbbell RADEON_GEM_DOMAIN_VRAM, 244254885Sdumbbell RADEON_GEM_DOMAIN_GTT); 245254885Sdumbbell break; 246254885Sdumbbell case 8: 247254885Sdumbbell /* VRAM to VRAM, buffer size sweep, common modes */ 248254885Sdumbbell for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 249254885Sdumbbell radeon_benchmark_move(rdev, common_modes[i], 250254885Sdumbbell RADEON_GEM_DOMAIN_VRAM, 251254885Sdumbbell RADEON_GEM_DOMAIN_VRAM); 252254885Sdumbbell break; 253254885Sdumbbell 254254885Sdumbbell default: 255254885Sdumbbell DRM_ERROR("Unknown benchmark\n"); 256254885Sdumbbell } 257254885Sdumbbell} 258