arm64: configs: synchronize with other 3399 config for 3399 linux
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / dma_memcpy_test.c
1 /*
2  *
3  * arch/arm/plat-rk/dma_memcpy_test.c
4  *
5  * Copyright (C) 2012 Rochchip.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * Author: hhb@rock-chips.com
13  * Create Date: 2012.03.26
14  * 
15  * HOW TO USE IT?
16  * enter the follow command at command line
17  * echo 1 > sys/module/dma_memcpy_test/parameters/debug   enable log output,default is enable
18  * echo 1000 > sys/module/dma_memcpy_test/parameters/interval   set dma transfer interval, default is 1000ms
19  * echo 1 > /sys/devices/platform/dma_memcpy.0/dmamemcpy  to start the dma test
20  *
21  */
22
23 /*
24 *               Driver Version Note
25 *
26 *v1.0 : 1. add dam thread number from 2 to 8;
27 *               
28 *               
29 */
30 #define VERSION_AND_TIME  "dma_memcpy_test.c v1.0 2012-08-13"
31
32 #include <linux/module.h>
33 #include <linux/platform_device.h>
34 #include <linux/irq.h>
35 #include <linux/io.h>
36 #include <linux/wait.h>
37 #include <linux/sched.h>
38 #include <linux/delay.h>
39 #include <asm/uaccess.h>
40 #include <asm/current.h>
41 #include <linux/init.h>
42 #include <linux/dma-mapping.h>
43 #include <linux/dmaengine.h>
44 #include <linux/amba/bus.h>
45 #include <linux/amba/pl330.h>
46 #include <linux/slab.h>
47
48
49 #define DMA_TEST_BUFFER_SIZE 512
50 #define DMA_THREAD  6
51
52 struct Dma_MemToMem {
53         const char *name;
54         unsigned char* src;                     //virtual address
55         unsigned char* dst;
56         int MenSize;
57     dma_cap_mask_t  cap_mask;
58         struct dma_chan *dma_chan;
59         struct dma_slave_config *config;
60         struct dma_async_tx_descriptor *tx;
61 };
62
63 //enable log output
64 static int debug = 8;
65 module_param(debug,int,S_IRUGO|S_IWUSR);
66 #define MEMCPY_DMA_DBG(fmt...)  {if(debug > 0) printk(fmt);}
67
68 static struct Dma_MemToMem DmaMemInfo[DMA_THREAD];
69
70 static void dma_memtest_transfer(struct Dma_MemToMem *DmaMemInfo)
71 {
72         dma_async_tx_descriptor_init(DmaMemInfo->tx, DmaMemInfo->dma_chan);
73         
74         dma_async_memcpy_buf_to_buf(DmaMemInfo->dma_chan, DmaMemInfo->dst,
75                         DmaMemInfo->src, DMA_TEST_BUFFER_SIZE);
76
77         dma_wait_for_async_tx(DmaMemInfo->tx);
78
79         dmaengine_terminate_all(DmaMemInfo->dma_chan);
80 }
81
82 //int slecount = 0;
83 static ssize_t memcpy_dma_read(struct device *device,struct device_attribute *attr, char *argv)
84 {
85
86      return 0;
87 }
88
89 static ssize_t memcpy_dma_write(struct device *device, struct device_attribute *attr, const char *argv, size_t count)
90 {
91  
92     int i,j;
93     printk("memcpy_dma_write\n");
94
95         for(j = DMA_THREAD; j > 0; j--)
96         {
97         memset(DmaMemInfo[j-1].src, ((j-1)<<4|(j-1)), DMA_TEST_BUFFER_SIZE);                    
98                 memset(DmaMemInfo[j-1].dst, 0x0, DMA_TEST_BUFFER_SIZE);
99         }
100
101         switch(DMA_THREAD) {            
102                 case 8:                 
103                         dma_memtest_transfer(&DmaMemInfo[7]);           
104                 case 7:                 
105                         dma_memtest_transfer(&DmaMemInfo[6]);   
106                 case 6:                 
107                         dma_memtest_transfer(&DmaMemInfo[5]);
108                 case 5:                 
109                         dma_memtest_transfer(&DmaMemInfo[4]);   
110                 case 4:                 
111                         dma_memtest_transfer(&DmaMemInfo[3]);   
112                 case 3:                 
113                         dma_memtest_transfer(&DmaMemInfo[2]);   
114                 case 2:                 
115                         dma_memtest_transfer(&DmaMemInfo[1]);   
116                 case 1:                 
117                         dma_memtest_transfer(&DmaMemInfo[0]);
118                         break;          
119                 default:                        
120                         printk("%s no channel\n", __func__);                    
121                 break;          
122         }
123         
124
125         for(i = 0; i < 16; i++) {       
126                 for(j = DMA_THREAD; j > 0; j--)
127                 {
128                         printk("src%d:%2x",j,*(DmaMemInfo[j-1].src + i*(DMA_TEST_BUFFER_SIZE/16)));                             
129                         printk(" -> dst%d:%2x\n",j,*(DmaMemInfo[j-1].dst + i*(DMA_TEST_BUFFER_SIZE/16)));       
130                 }
131         }       
132
133     return count;
134 }
135
136 static DEVICE_ATTR(dmamemcpy,  S_IRUGO|S_IALLUGO, memcpy_dma_read, memcpy_dma_write);
137
138
139 static int dma_memtest_channel_setup_and_init(struct Dma_MemToMem *DmaMemInfo, const char *name,
140                 u32 direction, u32 addr_width, u32 maxburst)
141 {
142         DmaMemInfo->name = name;
143         dma_cap_set(DMA_MEMCPY, DmaMemInfo->cap_mask);
144         DmaMemInfo->dma_chan = dma_request_channel(DmaMemInfo->cap_mask,NULL,NULL);
145
146         if(DmaMemInfo->dma_chan==NULL)
147         {
148                 printk("request dma_chan %s fail\n",DmaMemInfo->name);
149                 return -1;
150         }else
151         {
152                 printk("request dma_chan %s success\n",DmaMemInfo->name);
153         }
154
155         DmaMemInfo->config = kmalloc(sizeof(struct dma_slave_config *),GFP_KERNEL);
156         DmaMemInfo->tx = kmalloc(sizeof(struct dma_async_tx_descriptor *),GFP_KERNEL);
157         if(DmaMemInfo->config == NULL)
158         {
159                 printk("struct config kmalloc memory %s fail\n",DmaMemInfo->name);
160                 return -1;
161         }
162         else    
163         {
164                 printk("struct config kmalloc memory %s sucess\n",DmaMemInfo->name);
165         }
166         
167
168         DmaMemInfo->src = kmalloc(DMA_TEST_BUFFER_SIZE, GFP_KERNEL);
169         DmaMemInfo->dst = kmalloc(DMA_TEST_BUFFER_SIZE, GFP_KERNEL);
170         if(DmaMemInfo->src == NULL || DmaMemInfo->dst == NULL)
171         {
172                 printk("dma_alloc_coherent %s fail\n",DmaMemInfo->name);
173                 return -1;
174         }
175         else                                            
176         {
177                 printk("dma_alloc_coherent %s success\n",DmaMemInfo->name);
178         }
179
180         return 0;
181
182 }
183
184
185 static int dma_memcpy_probe(struct platform_device *pdev)
186 {
187     int ret;
188
189     ret = device_create_file(&pdev->dev, &dev_attr_dmamemcpy);
190         printk(">>>>>>>>>>>>>>>>>>>>> dam_test_probe <<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
191
192     switch(DMA_THREAD) {                
193                 case 8:                 
194                         dma_memtest_channel_setup_and_init(&DmaMemInfo[7], "DmaMemInfo[7]",
195                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);                        
196                 case 7:                 
197                         dma_memtest_channel_setup_and_init(&DmaMemInfo[6], "DmaMemInfo[6]",
198                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);        
199                 case 6:                 
200                         dma_memtest_channel_setup_and_init(&DmaMemInfo[5], "DmaMemInfo[5]",
201                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);        
202                 case 5:                 
203                         dma_memtest_channel_setup_and_init(&DmaMemInfo[4], "DmaMemInfo[4]",
204                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);                
205                 case 4:                 
206                         dma_memtest_channel_setup_and_init(&DmaMemInfo[3], "DmaMemInfo[3]",
207                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);                
208                 case 3:                 
209                         dma_memtest_channel_setup_and_init(&DmaMemInfo[2], "DmaMemInfo[2]",
210                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);        
211                 case 2:                 
212                         dma_memtest_channel_setup_and_init(&DmaMemInfo[1], "DmaMemInfo[1]",
213                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);        
214                 case 1:                 
215                         dma_memtest_channel_setup_and_init(&DmaMemInfo[0], "DmaMemInfo[0]",
216                 DMA_MEM_TO_MEM, DMA_SLAVE_BUSWIDTH_8_BYTES, 16);
217                         break;          
218                 default:                        
219                         printk("%s no channel\n", __func__);                    
220                 break;          
221         }
222         
223         printk("dma_memcpy_probe sucess\n");
224     return 0;
225 }
226
227 static int dma_memcpy_remove(struct platform_device *pdev)
228 {
229     device_remove_file(&pdev->dev, &dev_attr_dmamemcpy);
230
231     return 0;
232 }
233
234 static struct platform_driver dma_mempcy_driver = {
235         .driver = {
236                 .name   = "dma_memcpy",
237                 .owner  = THIS_MODULE,
238         },
239         .probe          = dma_memcpy_probe,
240         .remove         = dma_memcpy_remove,
241 };
242
243 struct platform_device rk29_device_dma_cpy = {
244         .name             = "dma_memcpy",
245         .id               = 0,
246
247 };
248
249
250 static int __init dma_test_init(void)
251 {
252                 platform_device_register(&rk29_device_dma_cpy);
253                 return platform_driver_register(&dma_mempcy_driver);
254 }
255
256 static void __exit dma_test_exit(void)
257 {
258                 dma_release_channel(DmaMemInfo[0].dma_chan);
259                 platform_driver_unregister(&dma_mempcy_driver);
260 }
261
262 late_initcall(dma_test_init);
263 module_exit(dma_test_exit);
264
265 MODULE_DESCRIPTION("RK29 PL330 Dma Test Deiver");
266 MODULE_LICENSE("GPL V2");
267 MODULE_AUTHOR("ZhenFu Fang <fzf@rock-chips.com>");
268 MODULE_AUTHOR("Hong Huibin<hhb@rock-chips.com>");