1 /*
2 * Copyright (c) 2023 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/dma.h>
11 #include "iut.h"
12 #if defined(CONFIG_CACHE_MANAGEMENT)
13 #include <zephyr/cache.h>
14 #else
15 #include "sedi_driver_core.h"
16 #endif
17 #include "sedi_driver_rtc.h"
18
19 #define DT_DRV_COMPAT intel_sedi_dma
20
21 __pinned_noinit static char __aligned(64) tx_data[4096];
22 __pinned_noinit static char __aligned(64) rx_data[4096];
23 static K_SEM_DEFINE(dma_sem, 0, 1);
24 static int dma_status;
25
test_done(const struct device * dev,void * user_data,uint32_t channel,int status)26 static void test_done(const struct device *dev, void *user_data, uint32_t channel, int status)
27 {
28 ARG_UNUSED(dev);
29 ARG_UNUSED(user_data);
30
31 if (status != 0) {
32 iut_case_print("DMA ch[%d] transfer error, status = %d\n", channel, status);
33 }
34 dma_status = status;
35 k_sem_give(&dma_sem);
36 }
37
test_dma_m2m(int argc,char ** argv)38 static int test_dma_m2m(int argc, char **argv)
39 {
40 struct dma_config dma_cfg = {0};
41 struct dma_block_config dma_block_cfg = {
42 .block_size = sizeof(tx_data),
43 .source_address = (uint32_t)&tx_data,
44 .dest_address = (uint32_t)&rx_data,
45 };
46 uint32_t test_len;
47 uint32_t blen = 8; /* burst length */
48 const struct device *const dma = DEVICE_DT_GET(DT_DRV_INST(0));
49 uint64_t us = sedi_rtc_get_us();
50
51 TEST_ASSERT_TRUE(dma != NULL);
52
53 if (argc) {
54 blen = (uint32_t)strtoul(argv[0], NULL, 0);
55 }
56 iut_case_print("Run with blen=%u\n", blen);
57
58 for (uint32_t i = 0; i < sizeof(tx_data); i++) {
59 tx_data[i] = (char)i;
60 }
61 #if defined(CONFIG_CACHE_MANAGEMENT)
62 sys_cache_data_flush_range(tx_data, sizeof(tx_data));
63 #else
64 sedi_core_inv_clean_dcache_by_addr((uint32_t *)tx_data, sizeof(tx_data));
65 #endif
66
67 dma_cfg.channel_direction = MEMORY_TO_MEMORY;
68 dma_cfg.source_data_size = 1;
69 dma_cfg.dest_data_size = 1;
70 dma_cfg.source_burst_length = blen;
71 dma_cfg.dest_burst_length = blen;
72 dma_cfg.dma_callback = test_done;
73 dma_cfg.complete_callback_en = 1;
74 dma_cfg.error_callback_dis = 1;
75 dma_cfg.block_count = 1;
76 dma_cfg.head_block = &dma_block_cfg;
77
78 for (test_len = 1; test_len <= sizeof(tx_data); test_len++) {
79 dma_block_cfg.block_size = test_len;
80
81 for (uint32_t chan_id = 0; chan_id < DT_INST_PROP(0, dma_channels); chan_id++) {
82 memset(rx_data, 0, sizeof(rx_data));
83
84 #if defined(CONFIG_CACHE_MANAGEMENT)
85 sys_cache_data_flush_range(rx_data, sizeof(rx_data));
86 #else
87 sedi_core_inv_clean_dcache_by_addr((uint32_t *)rx_data, sizeof(rx_data));
88 #endif
89
90 TEST_ASSERT_TRUE(!dma_config(dma, chan_id, &dma_cfg));
91 TEST_ASSERT_TRUE(!dma_start(dma, chan_id));
92
93 TEST_ASSERT_TRUE(!k_sem_take(&dma_sem, K_MSEC(1000)));
94 TEST_ASSERT_TRUE(dma_status == 0);
95 TEST_ASSERT_TRUE(!memcmp(tx_data, rx_data, test_len));
96 TEST_ASSERT_TRUE(!dma_stop(dma, chan_id));
97 }
98 }
99 us = sedi_rtc_get_us() - us;
100 iut_case_print("Test Done after %u | %u us\n", (uint32_t)(us >> 32), (uint32_t)us);
101
102 return IUT_ERR_OK;
103 }
104
105 DEFINE_IUT_CASE(dma_m2m, dma, IUT_ATTRI_NONE);
106