1 /* 2 * Copyright 2009 Jerome Glisse. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Jerome Glisse 23 */ 24 #include <drm/drmP.h> 25 #include <drm/radeon_drm.h> 26 #include "radeon_reg.h" 27 #include "radeon.h" 28 29 void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, 30 unsigned sdomain, unsigned ddomain) 31 { 32 struct radeon_bo *dobj = NULL; 33 struct radeon_bo *sobj = NULL; 34 struct radeon_fence *fence = NULL; 35 uint64_t saddr, daddr; 36 unsigned long start_jiffies; 37 unsigned long end_jiffies; 38 unsigned long time; 39 unsigned i, n, size; 40 int r; 41 42 size = bsize; 43 n = 1024; 44 r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, sdomain, &sobj); 45 if (r) { 46 goto out_cleanup; 47 } 48 r = radeon_bo_reserve(sobj, false); 49 if (unlikely(r != 0)) 50 goto out_cleanup; 51 r = radeon_bo_pin(sobj, sdomain, &saddr); 52 radeon_bo_unreserve(sobj); 53 if (r) { 54 goto out_cleanup; 55 } 56 r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, ddomain, &dobj); 57 if (r) { 58 goto out_cleanup; 59 } 60 r = radeon_bo_reserve(dobj, false); 61 if (unlikely(r != 0)) 62 goto out_cleanup; 63 r = radeon_bo_pin(dobj, ddomain, &daddr); 64 radeon_bo_unreserve(dobj); 65 if (r) { 66 goto out_cleanup; 67 } 68 69 /* r100 doesn't have dma engine so skip the test */ 70 if (rdev->asic->copy_dma) { 71 72 start_jiffies = jiffies; 73 for (i = 0; i < n; i++) { 74 r = radeon_fence_create(rdev, &fence); 75 if (r) { 76 goto out_cleanup; 77 } 78 79 r = radeon_copy_dma(rdev, saddr, daddr, 80 size / RADEON_GPU_PAGE_SIZE, fence); 81 82 if (r) { 83 goto out_cleanup; 84 } 85 r = radeon_fence_wait(fence, false); 86 if (r) { 87 goto out_cleanup; 88 } 89 radeon_fence_unref(&fence); 90 } 91 end_jiffies = jiffies; 92 time = end_jiffies - start_jiffies; 93 time = jiffies_to_msecs(time); 94 if (time > 0) { 95 i = ((n * size) >> 10) / time; 96 printk(KERN_INFO "radeon: dma %u bo moves of %ukb from" 97 " %d to %d in %lums (%ukb/ms %ukb/s %uM/s)\n", 98 n, size >> 10, 99 sdomain, ddomain, time, 100 i, i * 1000, (i * 1000) / 1024); 101 } 102 } 103 104 start_jiffies = jiffies; 105 for (i = 0; i < n; i++) { 106 r = radeon_fence_create(rdev, &fence); 107 if (r) { 108 goto out_cleanup; 109 } 110 r = radeon_copy_blit(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); 111 if (r) { 112 goto out_cleanup; 113 } 114 r = radeon_fence_wait(fence, false); 115 if (r) { 116 goto out_cleanup; 117 } 118 radeon_fence_unref(&fence); 119 } 120 end_jiffies = jiffies; 121 time = end_jiffies - start_jiffies; 122 time = jiffies_to_msecs(time); 123 if (time > 0) { 124 i = ((n * size) >> 10) / time; 125 printk(KERN_INFO "radeon: blit %u bo moves of %ukb from %d to %d" 126 " in %lums (%ukb/ms %ukb/s %uM/s)\n", n, size >> 10, 127 sdomain, ddomain, time, i, i * 1000, (i * 1000) / 1024); 128 } 129 out_cleanup: 130 if (sobj) { 131 r = radeon_bo_reserve(sobj, false); 132 if (likely(r == 0)) { 133 radeon_bo_unpin(sobj); 134 radeon_bo_unreserve(sobj); 135 } 136 radeon_bo_unref(&sobj); 137 } 138 if (dobj) { 139 r = radeon_bo_reserve(dobj, false); 140 if (likely(r == 0)) { 141 radeon_bo_unpin(dobj); 142 radeon_bo_unreserve(dobj); 143 } 144 radeon_bo_unref(&dobj); 145 } 146 if (fence) { 147 radeon_fence_unref(&fence); 148 } 149 if (r) { 150 printk(KERN_WARNING "Error while benchmarking BO move.\n"); 151 } 152 } 153 154 void radeon_benchmark(struct radeon_device *rdev) 155 { 156 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT, 157 RADEON_GEM_DOMAIN_VRAM); 158 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 159 RADEON_GEM_DOMAIN_GTT); 160 } 161