1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2023 Loongson Technology Corporation Limited
4  */
5 
6 #include <drm/drm_debugfs.h>
7 
8 #include "lsdc_benchmark.h"
9 #include "lsdc_drv.h"
10 #include "lsdc_gem.h"
11 #include "lsdc_ttm.h"
12 
13 typedef void (*lsdc_copy_proc_t)(struct lsdc_bo *src_bo,
14 				 struct lsdc_bo *dst_bo,
15 				 unsigned int size,
16 				 int n);
17 
18 static void lsdc_copy_gtt_to_vram_cpu(struct lsdc_bo *src_bo,
19 				      struct lsdc_bo *dst_bo,
20 				      unsigned int size,
21 				      int n)
22 {
23 	lsdc_bo_kmap(src_bo);
24 	lsdc_bo_kmap(dst_bo);
25 
26 	while (n--)
27 		memcpy_toio(dst_bo->kptr, src_bo->kptr, size);
28 
29 	lsdc_bo_kunmap(src_bo);
30 	lsdc_bo_kunmap(dst_bo);
31 }
32 
33 static void lsdc_copy_vram_to_gtt_cpu(struct lsdc_bo *src_bo,
34 				      struct lsdc_bo *dst_bo,
35 				      unsigned int size,
36 				      int n)
37 {
38 	lsdc_bo_kmap(src_bo);
39 	lsdc_bo_kmap(dst_bo);
40 
41 	while (n--)
42 		memcpy_fromio(dst_bo->kptr, src_bo->kptr, size);
43 
44 	lsdc_bo_kunmap(src_bo);
45 	lsdc_bo_kunmap(dst_bo);
46 }
47 
48 static void lsdc_copy_gtt_to_gtt_cpu(struct lsdc_bo *src_bo,
49 				     struct lsdc_bo *dst_bo,
50 				     unsigned int size,
51 				     int n)
52 {
53 	lsdc_bo_kmap(src_bo);
54 	lsdc_bo_kmap(dst_bo);
55 
56 	while (n--)
57 		memcpy(dst_bo->kptr, src_bo->kptr, size);
58 
59 	lsdc_bo_kunmap(src_bo);
60 	lsdc_bo_kunmap(dst_bo);
61 }
62 
63 static void lsdc_benchmark_copy(struct lsdc_device *ldev,
64 				unsigned int size,
65 				unsigned int n,
66 				u32 src_domain,
67 				u32 dst_domain,
68 				lsdc_copy_proc_t copy_proc,
69 				struct drm_printer *p)
70 {
71 	struct drm_device *ddev = &ldev->base;
72 	struct lsdc_bo *src_bo;
73 	struct lsdc_bo *dst_bo;
74 	unsigned long start_jiffies;
75 	unsigned long end_jiffies;
76 	unsigned int throughput;
77 	unsigned int time;
78 
79 	src_bo = lsdc_bo_create_kernel_pinned(ddev, src_domain, size);
80 	dst_bo = lsdc_bo_create_kernel_pinned(ddev, dst_domain, size);
81 
82 	start_jiffies = jiffies;
83 
84 	copy_proc(src_bo, dst_bo, size, n);
85 
86 	end_jiffies = jiffies;
87 
88 	lsdc_bo_free_kernel_pinned(src_bo);
89 	lsdc_bo_free_kernel_pinned(dst_bo);
90 
91 	time = jiffies_to_msecs(end_jiffies - start_jiffies);
92 
93 	throughput = (n * (size >> 10)) / time;
94 
95 	drm_printf(p,
96 		   "Copy bo of %uKiB %u times from %s to %s in %ums: %uMB/s\n",
97 		   size >> 10, n,
98 		   lsdc_domain_to_str(src_domain),
99 		   lsdc_domain_to_str(dst_domain),
100 		   time, throughput);
101 }
102 
103 int lsdc_show_benchmark_copy(struct lsdc_device *ldev, struct drm_printer *p)
104 {
105 	unsigned int buffer_size = 1920 * 1080 * 4;
106 	unsigned int iteration = 60;
107 
108 	lsdc_benchmark_copy(ldev,
109 			    buffer_size,
110 			    iteration,
111 			    LSDC_GEM_DOMAIN_GTT,
112 			    LSDC_GEM_DOMAIN_GTT,
113 			    lsdc_copy_gtt_to_gtt_cpu,
114 			    p);
115 
116 	lsdc_benchmark_copy(ldev,
117 			    buffer_size,
118 			    iteration,
119 			    LSDC_GEM_DOMAIN_GTT,
120 			    LSDC_GEM_DOMAIN_VRAM,
121 			    lsdc_copy_gtt_to_vram_cpu,
122 			    p);
123 
124 	lsdc_benchmark_copy(ldev,
125 			    buffer_size,
126 			    iteration,
127 			    LSDC_GEM_DOMAIN_VRAM,
128 			    LSDC_GEM_DOMAIN_GTT,
129 			    lsdc_copy_vram_to_gtt_cpu,
130 			    p);
131 
132 	return 0;
133 }
134