aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dmatest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/dmatest.c')
-rw-r--r--drivers/dma/dmatest.c110
1 files changed, 59 insertions, 51 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index a07ef3d6b3ec..34ff53290b03 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -52,15 +52,10 @@ module_param(iterations, uint, S_IRUGO | S_IWUSR);
52MODULE_PARM_DESC(iterations, 52MODULE_PARM_DESC(iterations,
53 "Iterations before stopping test (default: infinite)"); 53 "Iterations before stopping test (default: infinite)");
54 54
55static unsigned int sg_buffers = 1;
56module_param(sg_buffers, uint, S_IRUGO | S_IWUSR);
57MODULE_PARM_DESC(sg_buffers,
58 "Number of scatter gather buffers (default: 1)");
59
60static unsigned int dmatest; 55static unsigned int dmatest;
61module_param(dmatest, uint, S_IRUGO | S_IWUSR); 56module_param(dmatest, uint, S_IRUGO | S_IWUSR);
62MODULE_PARM_DESC(dmatest, 57MODULE_PARM_DESC(dmatest,
63 "dmatest 0-memcpy 1-slave_sg (default: 0)"); 58 "dmatest 0-memcpy 1-memset (default: 0)");
64 59
65static unsigned int xor_sources = 3; 60static unsigned int xor_sources = 3;
66module_param(xor_sources, uint, S_IRUGO | S_IWUSR); 61module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
@@ -158,6 +153,7 @@ MODULE_PARM_DESC(run, "Run the test (default: false)");
158#define PATTERN_COPY 0x40 153#define PATTERN_COPY 0x40
159#define PATTERN_OVERWRITE 0x20 154#define PATTERN_OVERWRITE 0x20
160#define PATTERN_COUNT_MASK 0x1f 155#define PATTERN_COUNT_MASK 0x1f
156#define PATTERN_MEMSET_IDX 0x01
161 157
162struct dmatest_thread { 158struct dmatest_thread {
163 struct list_head node; 159 struct list_head node;
@@ -239,46 +235,62 @@ static unsigned long dmatest_random(void)
239 return buf; 235 return buf;
240} 236}
241 237
238static inline u8 gen_inv_idx(u8 index, bool is_memset)
239{
240 u8 val = is_memset ? PATTERN_MEMSET_IDX : index;
241
242 return ~val & PATTERN_COUNT_MASK;
243}
244
245static inline u8 gen_src_value(u8 index, bool is_memset)
246{
247 return PATTERN_SRC | gen_inv_idx(index, is_memset);
248}
249
250static inline u8 gen_dst_value(u8 index, bool is_memset)
251{
252 return PATTERN_DST | gen_inv_idx(index, is_memset);
253}
254
242static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len, 255static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
243 unsigned int buf_size) 256 unsigned int buf_size, bool is_memset)
244{ 257{
245 unsigned int i; 258 unsigned int i;
246 u8 *buf; 259 u8 *buf;
247 260
248 for (; (buf = *bufs); bufs++) { 261 for (; (buf = *bufs); bufs++) {
249 for (i = 0; i < start; i++) 262 for (i = 0; i < start; i++)
250 buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); 263 buf[i] = gen_src_value(i, is_memset);
251 for ( ; i < start + len; i++) 264 for ( ; i < start + len; i++)
252 buf[i] = PATTERN_SRC | PATTERN_COPY 265 buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY;
253 | (~i & PATTERN_COUNT_MASK);
254 for ( ; i < buf_size; i++) 266 for ( ; i < buf_size; i++)
255 buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); 267 buf[i] = gen_src_value(i, is_memset);
256 buf++; 268 buf++;
257 } 269 }
258} 270}
259 271
260static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len, 272static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
261 unsigned int buf_size) 273 unsigned int buf_size, bool is_memset)
262{ 274{
263 unsigned int i; 275 unsigned int i;
264 u8 *buf; 276 u8 *buf;
265 277
266 for (; (buf = *bufs); bufs++) { 278 for (; (buf = *bufs); bufs++) {
267 for (i = 0; i < start; i++) 279 for (i = 0; i < start; i++)
268 buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); 280 buf[i] = gen_dst_value(i, is_memset);
269 for ( ; i < start + len; i++) 281 for ( ; i < start + len; i++)
270 buf[i] = PATTERN_DST | PATTERN_OVERWRITE 282 buf[i] = gen_dst_value(i, is_memset) |
271 | (~i & PATTERN_COUNT_MASK); 283 PATTERN_OVERWRITE;
272 for ( ; i < buf_size; i++) 284 for ( ; i < buf_size; i++)
273 buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); 285 buf[i] = gen_dst_value(i, is_memset);
274 } 286 }
275} 287}
276 288
277static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, 289static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
278 unsigned int counter, bool is_srcbuf) 290 unsigned int counter, bool is_srcbuf, bool is_memset)
279{ 291{
280 u8 diff = actual ^ pattern; 292 u8 diff = actual ^ pattern;
281 u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); 293 u8 expected = pattern | gen_inv_idx(counter, is_memset);
282 const char *thread_name = current->comm; 294 const char *thread_name = current->comm;
283 295
284 if (is_srcbuf) 296 if (is_srcbuf)
@@ -298,7 +310,7 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
298 310
299static unsigned int dmatest_verify(u8 **bufs, unsigned int start, 311static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
300 unsigned int end, unsigned int counter, u8 pattern, 312 unsigned int end, unsigned int counter, u8 pattern,
301 bool is_srcbuf) 313 bool is_srcbuf, bool is_memset)
302{ 314{
303 unsigned int i; 315 unsigned int i;
304 unsigned int error_count = 0; 316 unsigned int error_count = 0;
@@ -311,11 +323,12 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
311 counter = counter_orig; 323 counter = counter_orig;
312 for (i = start; i < end; i++) { 324 for (i = start; i < end; i++) {
313 actual = buf[i]; 325 actual = buf[i];
314 expected = pattern | (~counter & PATTERN_COUNT_MASK); 326 expected = pattern | gen_inv_idx(counter, is_memset);
315 if (actual != expected) { 327 if (actual != expected) {
316 if (error_count < MAX_ERROR_COUNT) 328 if (error_count < MAX_ERROR_COUNT)
317 dmatest_mismatch(actual, pattern, i, 329 dmatest_mismatch(actual, pattern, i,
318 counter, is_srcbuf); 330 counter, is_srcbuf,
331 is_memset);
319 error_count++; 332 error_count++;
320 } 333 }
321 counter++; 334 counter++;
@@ -435,6 +448,7 @@ static int dmatest_func(void *data)
435 s64 runtime = 0; 448 s64 runtime = 0;
436 unsigned long long total_len = 0; 449 unsigned long long total_len = 0;
437 u8 align = 0; 450 u8 align = 0;
451 bool is_memset = false;
438 452
439 set_freezable(); 453 set_freezable();
440 454
@@ -448,9 +462,10 @@ static int dmatest_func(void *data)
448 if (thread->type == DMA_MEMCPY) { 462 if (thread->type == DMA_MEMCPY) {
449 align = dev->copy_align; 463 align = dev->copy_align;
450 src_cnt = dst_cnt = 1; 464 src_cnt = dst_cnt = 1;
451 } else if (thread->type == DMA_SG) { 465 } else if (thread->type == DMA_MEMSET) {
452 align = dev->copy_align; 466 align = dev->fill_align;
453 src_cnt = dst_cnt = sg_buffers; 467 src_cnt = dst_cnt = 1;
468 is_memset = true;
454 } else if (thread->type == DMA_XOR) { 469 } else if (thread->type == DMA_XOR) {
455 /* force odd to ensure dst = src */ 470 /* force odd to ensure dst = src */
456 src_cnt = min_odd(params->xor_sources | 1, dev->max_xor); 471 src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
@@ -530,8 +545,6 @@ static int dmatest_func(void *data)
530 dma_addr_t srcs[src_cnt]; 545 dma_addr_t srcs[src_cnt];
531 dma_addr_t *dsts; 546 dma_addr_t *dsts;
532 unsigned int src_off, dst_off, len; 547 unsigned int src_off, dst_off, len;
533 struct scatterlist tx_sg[src_cnt];
534 struct scatterlist rx_sg[src_cnt];
535 548
536 total_tests++; 549 total_tests++;
537 550
@@ -571,9 +584,9 @@ static int dmatest_func(void *data)
571 dst_off = (dst_off >> align) << align; 584 dst_off = (dst_off >> align) << align;
572 585
573 dmatest_init_srcs(thread->srcs, src_off, len, 586 dmatest_init_srcs(thread->srcs, src_off, len,
574 params->buf_size); 587 params->buf_size, is_memset);
575 dmatest_init_dsts(thread->dsts, dst_off, len, 588 dmatest_init_dsts(thread->dsts, dst_off, len,
576 params->buf_size); 589 params->buf_size, is_memset);
577 590
578 diff = ktime_sub(ktime_get(), start); 591 diff = ktime_sub(ktime_get(), start);
579 filltime = ktime_add(filltime, diff); 592 filltime = ktime_add(filltime, diff);
@@ -627,22 +640,15 @@ static int dmatest_func(void *data)
627 um->bidi_cnt++; 640 um->bidi_cnt++;
628 } 641 }
629 642
630 sg_init_table(tx_sg, src_cnt);
631 sg_init_table(rx_sg, src_cnt);
632 for (i = 0; i < src_cnt; i++) {
633 sg_dma_address(&rx_sg[i]) = srcs[i];
634 sg_dma_address(&tx_sg[i]) = dsts[i] + dst_off;
635 sg_dma_len(&tx_sg[i]) = len;
636 sg_dma_len(&rx_sg[i]) = len;
637 }
638
639 if (thread->type == DMA_MEMCPY) 643 if (thread->type == DMA_MEMCPY)
640 tx = dev->device_prep_dma_memcpy(chan, 644 tx = dev->device_prep_dma_memcpy(chan,
641 dsts[0] + dst_off, 645 dsts[0] + dst_off,
642 srcs[0], len, flags); 646 srcs[0], len, flags);
643 else if (thread->type == DMA_SG) 647 else if (thread->type == DMA_MEMSET)
644 tx = dev->device_prep_dma_sg(chan, tx_sg, src_cnt, 648 tx = dev->device_prep_dma_memset(chan,
645 rx_sg, src_cnt, flags); 649 dsts[0] + dst_off,
650 *(thread->srcs[0] + src_off),
651 len, flags);
646 else if (thread->type == DMA_XOR) 652 else if (thread->type == DMA_XOR)
647 tx = dev->device_prep_dma_xor(chan, 653 tx = dev->device_prep_dma_xor(chan,
648 dsts[0] + dst_off, 654 dsts[0] + dst_off,
@@ -722,23 +728,25 @@ static int dmatest_func(void *data)
722 start = ktime_get(); 728 start = ktime_get();
723 pr_debug("%s: verifying source buffer...\n", current->comm); 729 pr_debug("%s: verifying source buffer...\n", current->comm);
724 error_count = dmatest_verify(thread->srcs, 0, src_off, 730 error_count = dmatest_verify(thread->srcs, 0, src_off,
725 0, PATTERN_SRC, true); 731 0, PATTERN_SRC, true, is_memset);
726 error_count += dmatest_verify(thread->srcs, src_off, 732 error_count += dmatest_verify(thread->srcs, src_off,
727 src_off + len, src_off, 733 src_off + len, src_off,
728 PATTERN_SRC | PATTERN_COPY, true); 734 PATTERN_SRC | PATTERN_COPY, true, is_memset);
729 error_count += dmatest_verify(thread->srcs, src_off + len, 735 error_count += dmatest_verify(thread->srcs, src_off + len,
730 params->buf_size, src_off + len, 736 params->buf_size, src_off + len,
731 PATTERN_SRC, true); 737 PATTERN_SRC, true, is_memset);
732 738
733 pr_debug("%s: verifying dest buffer...\n", current->comm); 739 pr_debug("%s: verifying dest buffer...\n", current->comm);
734 error_count += dmatest_verify(thread->dsts, 0, dst_off, 740 error_count += dmatest_verify(thread->dsts, 0, dst_off,
735 0, PATTERN_DST, false); 741 0, PATTERN_DST, false, is_memset);
742
736 error_count += dmatest_verify(thread->dsts, dst_off, 743 error_count += dmatest_verify(thread->dsts, dst_off,
737 dst_off + len, src_off, 744 dst_off + len, src_off,
738 PATTERN_SRC | PATTERN_COPY, false); 745 PATTERN_SRC | PATTERN_COPY, false, is_memset);
746
739 error_count += dmatest_verify(thread->dsts, dst_off + len, 747 error_count += dmatest_verify(thread->dsts, dst_off + len,
740 params->buf_size, dst_off + len, 748 params->buf_size, dst_off + len,
741 PATTERN_DST, false); 749 PATTERN_DST, false, is_memset);
742 750
743 diff = ktime_sub(ktime_get(), start); 751 diff = ktime_sub(ktime_get(), start);
744 comparetime = ktime_add(comparetime, diff); 752 comparetime = ktime_add(comparetime, diff);
@@ -821,8 +829,8 @@ static int dmatest_add_threads(struct dmatest_info *info,
821 829
822 if (type == DMA_MEMCPY) 830 if (type == DMA_MEMCPY)
823 op = "copy"; 831 op = "copy";
824 else if (type == DMA_SG) 832 else if (type == DMA_MEMSET)
825 op = "sg"; 833 op = "set";
826 else if (type == DMA_XOR) 834 else if (type == DMA_XOR)
827 op = "xor"; 835 op = "xor";
828 else if (type == DMA_PQ) 836 else if (type == DMA_PQ)
@@ -883,9 +891,9 @@ static int dmatest_add_channel(struct dmatest_info *info,
883 } 891 }
884 } 892 }
885 893
886 if (dma_has_cap(DMA_SG, dma_dev->cap_mask)) { 894 if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
887 if (dmatest == 1) { 895 if (dmatest == 1) {
888 cnt = dmatest_add_threads(info, dtc, DMA_SG); 896 cnt = dmatest_add_threads(info, dtc, DMA_MEMSET);
889 thread_count += cnt > 0 ? cnt : 0; 897 thread_count += cnt > 0 ? cnt : 0;
890 } 898 }
891 } 899 }
@@ -961,8 +969,8 @@ static void run_threaded_test(struct dmatest_info *info)
961 params->noverify = noverify; 969 params->noverify = noverify;
962 970
963 request_channels(info, DMA_MEMCPY); 971 request_channels(info, DMA_MEMCPY);
972 request_channels(info, DMA_MEMSET);
964 request_channels(info, DMA_XOR); 973 request_channels(info, DMA_XOR);
965 request_channels(info, DMA_SG);
966 request_channels(info, DMA_PQ); 974 request_channels(info, DMA_PQ);
967} 975}
968 976