fix rga suspend disable clock error bug
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rga / rga_drv.c
1 /* \r
2  * Copyright (C) 2012 ROCKCHIP, Inc.\r
3  *\r
4  * This software is licensed under the terms of the GNU General Public\r
5  * License version 2, as published by the Free Software Foundation, and\r
6  * may be copied, distributed, and modified under those terms.\r
7  *\r
8  * This program is distributed in the hope that it will be useful,\r
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
11  * GNU General Public License for more details.\r
12  * \r
13  */\r
14 \r
15 #include <linux/kernel.h>\r
16 #include <linux/init.h>\r
17 #include <linux/module.h>\r
18 #include <linux/platform_device.h>\r
19 #include <linux/sched.h>\r
20 #include <linux/mutex.h>\r
21 #include <linux/err.h>\r
22 #include <linux/clk.h>\r
23 #include <asm/delay.h>\r
24 #include <linux/dma-mapping.h>\r
25 #include <linux/delay.h>\r
26 #include <asm/io.h>\r
27 #include <linux/irq.h>\r
28 #include <linux/interrupt.h>\r
29 #include <mach/io.h>\r
30 #include <mach/irqs.h>\r
31 #include <linux/fs.h>\r
32 #include <asm/uaccess.h>\r
33 #include <linux/firmware.h>\r
34 #include <linux/miscdevice.h>\r
35 #include <linux/poll.h>\r
36 #include <linux/delay.h>\r
37 #include <linux/wait.h>\r
38 #include <linux/syscalls.h>\r
39 #include <linux/timer.h>\r
40 #include <linux/time.h>\r
41 #include <asm/cacheflush.h>\r
42 #include <linux/compiler.h>\r
43 #include <linux/slab.h>\r
44 #include <linux/fb.h>\r
45 \r
46 \r
47 #include "rga.h"\r
48 #include "rga_reg_info.h"\r
49 #include "rga_mmu_info.h"\r
50 #include "RGA_API.h"\r
51 \r
52 #define RGA_TEST 0\r
53 #define RGA_TEST_TIME 0\r
54 #define RGA_TEST_FLUSH_TIME 0\r
55 \r
56 \r
57 #define PRE_SCALE_BUF_SIZE  2048*1024*4\r
58 \r
59 #define RGA_POWER_OFF_DELAY     4*HZ /* 4s */\r
60 #define RGA_TIMEOUT_DELAY       1*HZ /* 1s */\r
61 \r
62 #define RGA_MAJOR               255\r
63 \r
64 #define RK30_RGA_PHYS   0x10114000\r
65 #define RK30_RGA_SIZE   SZ_8K\r
66 #define RGA_RESET_TIMEOUT       1000\r
67 \r
68 /* Driver information */\r
69 #define DRIVER_DESC             "RGA Device Driver"\r
70 #define DRIVER_NAME             "rga"\r
71 \r
72 ktime_t rga_start;\r
73 ktime_t rga_end;\r
74 \r
75 int rga_num = 0;\r
76 \r
77 struct rga_drvdata {\r
78         struct miscdevice miscdev;\r
79         struct device dev;\r
80         void *rga_base;\r
81         int irq0;\r
82         \r
83         struct delayed_work power_off_work;\r
84         void (*rga_irq_callback)(int rga_retval);   //callback function used by aync call\r
85 };\r
86 \r
87 \r
88 static struct rga_drvdata *drvdata = NULL;\r
89 rga_service_info rga_service;\r
90 \r
91 static struct clk *aclk_rga;\r
92 static struct clk *hclk_rga;\r
93 \r
94 \r
95 static int rga_blit_async(rga_session *session, struct rga_req *req);\r
96 static void rga_del_running_list(void);\r
97 \r
98 \r
99 /* Logging */\r
100 #define RGA_DEBUG 1\r
101 #if RGA_DEBUG\r
102 #define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args)\r
103 #define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args)\r
104 #define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args)\r
105 #define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args)\r
106 #else\r
107 #define DBG(format, args...)\r
108 #define ERR(format, args...)\r
109 #define WARNING(format, args...)\r
110 #define INFO(format, args...)\r
111 #endif\r
112 \r
113 \r
114 static inline void rga_write(u32 b, u32 r)\r
115 {\r
116         __raw_writel(b, drvdata->rga_base + r);\r
117 }\r
118 \r
119 static inline u32 rga_read(u32 r)\r
120 {\r
121         return __raw_readl(drvdata->rga_base + r);\r
122 }\r
123 \r
124 static void rga_soft_reset(void)\r
125 {\r
126         u32 i;\r
127         u32 reg;\r
128 \r
129         rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL\r
130 \r
131         for(i = 0; i < RGA_RESET_TIMEOUT; i++) \r
132     {\r
133                 reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL\r
134 \r
135                 if(reg == 0)\r
136                         break;\r
137 \r
138                 udelay(1);\r
139         }\r
140 \r
141         if(i == RGA_RESET_TIMEOUT)\r
142                 ERR("soft reset timeout.\n");\r
143 }\r
144 \r
145 static void rga_dump(void)\r
146 {\r
147         int running;\r
148     int num_done;\r
149     struct rga_reg *reg, *reg_tmp;\r
150     rga_session *session, *session_tmp;    \r
151     struct list_head *next; \r
152 \r
153         running = atomic_read(&rga_service.total_running);\r
154         printk("rga total_running %d\n", running);\r
155 \r
156     /* Dump waiting list info */\r
157     if (!list_empty(&rga_service.waiting))\r
158     {        \r
159         next = &rga_service.waiting;\r
160 \r
161         printk("rga_service dump waiting list\n");\r
162 \r
163         do\r
164         {\r
165             reg = list_entry(next->next, struct rga_reg, status_link);\r
166             running = atomic_read(&reg->session->task_running);\r
167             num_done = atomic_read(&reg->session->num_done);\r
168             printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running);                       \r
169             next = next->next;\r
170         }\r
171         while(!list_empty(next));                        \r
172     }\r
173 \r
174     /* Dump running list info */\r
175     if (!list_empty(&rga_service.running))\r
176     {\r
177         printk("rga_service dump running list\n");\r
178             \r
179         next = &rga_service.running;\r
180         do\r
181         {\r
182             reg = list_entry(next->next, struct rga_reg, status_link);\r
183             running = atomic_read(&reg->session->task_running);\r
184             num_done = atomic_read(&reg->session->num_done);\r
185             printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running);                       \r
186             next = next->next;\r
187         }\r
188         while(!list_empty(next));                            \r
189     }\r
190     \r
191 \r
192         list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) \r
193     {\r
194                 printk("session pid %d:\n", session->pid);\r
195                 running = atomic_read(&session->task_running);\r
196                 printk("task_running %d\n", running);\r
197                 list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) \r
198         {\r
199                         printk("waiting register set 0x%.8x\n", (unsigned int)reg);\r
200                 }\r
201                 list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) \r
202         {\r
203                         printk("running register set 0x%.8x\n", (unsigned int)reg);\r
204                 }\r
205         }\r
206 }\r
207 \r
208 \r
209 static void rga_power_on(void)\r
210 {\r
211         //printk("rga_power_on\n");\r
212         //cancel_delayed_work_sync(&drvdata->power_off_work);\r
213         if (rga_service.enable)\r
214                 return;\r
215 \r
216     spin_lock_bh(&rga_service.lock);\r
217         clk_enable(aclk_rga);\r
218         clk_enable(hclk_rga);\r
219         rga_service.enable = true;\r
220     spin_unlock_bh(&rga_service.lock);\r
221 }\r
222 \r
223 \r
224 static void rga_power_off(void)\r
225 {\r
226     int total_running;\r
227     \r
228     \r
229         if(!rga_service.enable)\r
230                 return;\r
231 \r
232     rga_service.enable = false;\r
233 \r
234     printk("rga_power_off\n");\r
235 \r
236     total_running = atomic_read(&rga_service.total_running);\r
237         if (total_running) {\r
238                 pr_alert("power off when %d task running!!\n", total_running);               \r
239                 mdelay(50);\r
240                 pr_alert("delay 50 ms for running task\n");        \r
241         rga_dump();\r
242         }\r
243     \r
244         clk_disable(aclk_rga);\r
245         clk_disable(hclk_rga);\r
246         \r
247 }\r
248 \r
249 static int rga_flush(rga_session *session, unsigned long arg)\r
250 {       \r
251     int ret = 0;\r
252     int ret_timeout;\r
253     \r
254     #if RGA_TEST_FLUSH_TIME\r
255     ktime_t start;\r
256     ktime_t end;\r
257     start = ktime_get();\r
258     #endif\r
259 \r
260     ret_timeout = wait_event_interruptible_timeout(session->wait, atomic_read(&session->done), RGA_TIMEOUT_DELAY);    \r
261     \r
262         if (unlikely(ret_timeout < 0)) {\r
263                 pr_err("flush pid %d wait task ret %d\n", session->pid, ret);                    \r
264         rga_soft_reset();\r
265         ret = -ETIMEDOUT;\r
266         } else if (0 == ret_timeout) {\r
267                 pr_err("flush pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));\r
268         printk("bus  = %.8x\n", rga_read(RGA_INT));\r
269         rga_soft_reset();\r
270                 ret = -ETIMEDOUT;\r
271         }\r
272 \r
273     #if RGA_TEST_FLUSH_TIME\r
274     end = ktime_get();\r
275     end = ktime_sub(end, start);\r
276     printk("one flush wait time %d\n", (int)ktime_to_us(end));\r
277     #endif\r
278     \r
279         return ret;\r
280 }\r
281 \r
282 \r
283 static int rga_get_result(rga_session *session, unsigned long arg)\r
284 {\r
285         //printk("rga_get_result %d\n",drvdata->rga_result);\r
286         \r
287     int ret = 0;\r
288 \r
289     int num_done;\r
290 \r
291     num_done = atomic_read(&session->num_done);\r
292         \r
293         if (unlikely(copy_to_user((void __user *)arg, &num_done, sizeof(int)))) {\r
294                         printk("copy_to_user failed\n");\r
295                         ERR("copy_to_user failed\n");\r
296                         ret =  -EFAULT; \r
297                 }\r
298         return ret;\r
299 }\r
300 \r
301 \r
302 \r
303 static int rga_check_param(const struct rga_req *req)\r
304 {\r
305         /*RGA can support up to 8192*8192 resolution in RGB format,but we limit the image size to 8191*8191 here*/\r
306         //check src width and height\r
307 \r
308     if(!((req->render_mode == color_fill_mode) || (req->render_mode == line_point_drawing_mode)))\r
309     {\r
310         if (unlikely((req->src.act_w <= 0) || (req->src.act_w > 8191) || (req->src.act_h <= 0) || (req->src.act_h > 8191))) \r
311         {\r
312                 ERR("invalid source resolution act_w = %d, act_h = %d\n", req->src.act_w, req->src.act_h);\r
313                 return  -EINVAL;\r
314         }\r
315     }\r
316 \r
317         //check dst width and height\r
318         if (unlikely((req->dst.act_w <= 0) || (req->dst.act_w > 2048) || (req->dst.act_h <= 0) || (req->dst.act_h > 2048))) \r
319     {\r
320                 ERR("invalid destination resolution act_w = %d, act_h = %d\n", req->dst.act_w, req->dst.act_h);\r
321                 return  -EINVAL;\r
322         }\r
323 \r
324         //check src_vir_w\r
325         if(unlikely(req->src.vir_w < req->src.act_w)){\r
326                 ERR("invalid src_vir_w\n");\r
327                 return  -EINVAL;\r
328         }\r
329 \r
330         //check dst_vir_w\r
331         if(unlikely(req->dst.vir_w < req->dst.act_w)){\r
332                 ERR("invalid dst_vir_w\n");\r
333                 return  -EINVAL;\r
334         }\r
335                 \r
336         return 0;\r
337 }\r
338 \r
339 static void rga_copy_reg(struct rga_reg *reg, uint32_t offset)\r
340 {   \r
341     uint32_t i;\r
342     uint32_t *cmd_buf;\r
343     uint32_t *reg_p;\r
344     \r
345     atomic_add(1, &rga_service.cmd_num);\r
346         atomic_add(1, &reg->session->task_running);\r
347     \r
348     cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*28;\r
349     reg_p = (uint32_t *)reg->cmd_reg;\r
350 \r
351     for(i=0; i<28; i++)\r
352     {\r
353         cmd_buf[i] = reg_p[i];\r
354     }\r
355     \r
356     dsb();\r
357 }\r
358 \r
359 \r
360 static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req)\r
361 {\r
362     unsigned long flag;\r
363     uint32_t ret;\r
364         struct rga_reg *reg = kmalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
365         if (NULL == reg) {\r
366                 pr_err("kmalloc fail in rga_reg_init\n");\r
367                 return NULL;\r
368         }\r
369 \r
370     reg->session = session;\r
371         INIT_LIST_HEAD(&reg->session_link);\r
372         INIT_LIST_HEAD(&reg->status_link);\r
373             \r
374     if (req->mmu_info.mmu_en)\r
375     {\r
376         ret = rga_set_mmu_info(reg, req);\r
377         if(ret < 0) \r
378         {\r
379             printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
380             if(reg != NULL) \r
381             {            \r
382                 kfree(reg);\r
383             }\r
384             return NULL; \r
385         }\r
386     }\r
387 \r
388     if(RGA_gen_reg_info(req, (uint8_t *)reg->cmd_reg) == -1)\r
389     {\r
390         printk("gen reg info error\n");\r
391         if(reg != NULL)\r
392         {\r
393             kfree(reg);            \r
394         }\r
395         return NULL;\r
396     }\r
397 \r
398     spin_lock_irqsave(&rga_service.lock, flag);\r
399         list_add_tail(&reg->status_link, &rga_service.waiting);\r
400         list_add_tail(&reg->session_link, &session->waiting);\r
401         spin_unlock_irqrestore(&rga_service.lock, flag);\r
402 \r
403     return reg;\r
404 }\r
405 \r
406 static struct rga_reg * rga_reg_init_2(rga_session *session, struct rga_req *req0, struct rga_req *req1)\r
407 {\r
408     unsigned long flag;\r
409     uint32_t ret;\r
410 \r
411     struct rga_reg *reg0, *reg1;\r
412 \r
413     reg0 = NULL;\r
414     reg1 = NULL;\r
415 \r
416     do\r
417     {    \r
418         reg0 = kmalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
419         if (NULL == reg0) {\r
420                 pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__);\r
421             break;\r
422         }\r
423 \r
424         reg1 = kmalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
425         if (NULL == reg1) {\r
426                 pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__);\r
427             break;\r
428         }\r
429 \r
430         reg0->session = session;        \r
431         INIT_LIST_HEAD(&reg0->session_link);\r
432         INIT_LIST_HEAD(&reg0->status_link);\r
433 \r
434         reg1->session = session;\r
435         INIT_LIST_HEAD(&reg1->session_link);\r
436         INIT_LIST_HEAD(&reg1->status_link);\r
437 \r
438         if(req0->mmu_info.mmu_en)\r
439         {\r
440             ret = rga_set_mmu_info(reg0, req0);\r
441             if(ret < 0) {\r
442                 printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
443                 break;        \r
444             }\r
445         }\r
446         \r
447         RGA_gen_reg_info(req0, (uint8_t *)reg0->cmd_reg);\r
448         \r
449         if(req1->mmu_info.mmu_en)\r
450         {\r
451             ret = rga_set_mmu_info(reg1, req1);\r
452             if(ret < 0) {\r
453                 printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
454                 break;        \r
455             }\r
456         }\r
457                 \r
458         RGA_gen_reg_info(req1, (uint8_t *)reg1->cmd_reg);\r
459         \r
460         spin_lock_irqsave(&rga_service.lock, flag);\r
461         list_add_tail(&reg0->status_link, &rga_service.waiting);\r
462         list_add_tail(&reg0->session_link, &session->waiting);\r
463         list_add_tail(&reg1->status_link, &rga_service.waiting);            \r
464         list_add_tail(&reg1->session_link, &session->waiting);\r
465         spin_unlock_irqrestore(&rga_service.lock, flag);\r
466 \r
467         return reg1;\r
468     }\r
469     while(0);\r
470 \r
471     if(reg0 != NULL) {\r
472         kfree(reg0);\r
473     }\r
474 \r
475     if(reg1 != NULL) {\r
476         kfree(reg1);\r
477     }\r
478 \r
479     return NULL;\r
480 }\r
481 \r
482 \r
483 static void rga_reg_deinit(struct rga_reg *reg)\r
484 {\r
485         list_del_init(&reg->session_link);\r
486         list_del_init(&reg->status_link);\r
487         kfree(reg);     \r
488 }\r
489 \r
490 static void rga_reg_from_wait_to_run(struct rga_reg *reg)\r
491 {\r
492         list_del_init(&reg->status_link);\r
493         list_add_tail(&reg->status_link, &rga_service.running);\r
494 \r
495         list_del_init(&reg->session_link);\r
496         list_add_tail(&reg->session_link, &reg->session->running);\r
497 }\r
498 \r
499 static void rga_service_session_clear(rga_session *session)\r
500 {\r
501         struct rga_reg *reg, *n;\r
502 \r
503     list_for_each_entry_safe(reg, n, &session->waiting, session_link) \r
504     {\r
505                 rga_reg_deinit(reg);\r
506         }\r
507 \r
508     list_for_each_entry_safe(reg, n, &session->running, session_link) \r
509     {\r
510                 rga_reg_deinit(reg);\r
511         }\r
512 }\r
513 \r
514 \r
515 static void rga_try_set_reg(uint32_t num)\r
516 {\r
517     unsigned long flag;\r
518     struct rga_reg *reg ;\r
519     \r
520     if (!num)\r
521     {\r
522         #if RGA_TEST        \r
523         printk("rga try set reg cmd num is 0\n");\r
524         #endif\r
525         \r
526         return;\r
527     }\r
528         \r
529         spin_lock_irqsave(&rga_service.lock, flag);\r
530         if (!list_empty(&rga_service.waiting)) \r
531     {\r
532         do\r
533         {                        \r
534             if(!list_empty(&rga_service.running)) \r
535             {                   \r
536                 break;\r
537             }\r
538             else \r
539             {  \r
540                 /* RGA is idle */\r
541                 reg = list_entry(rga_service.waiting.next, struct rga_reg, status_link);                \r
542                 rga_soft_reset();\r
543                 //rga_del_running_list();\r
544                 rga_copy_reg(reg, 0);            \r
545                 rga_reg_from_wait_to_run(reg);\r
546                 \r
547                 dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[28]);\r
548                 outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[28]));\r
549 \r
550                 /*  \r
551                  *  if cmd buf must use mmu\r
552                  *  it should be configured before cmd start  \r
553                  */\r
554                 rga_write((2<<4)|0x1, RGA_MMU_CTRL);               \r
555                 \r
556                 rga_write(virt_to_phys(reg->MMU_base)>>2, RGA_MMU_TBL);\r
557                                 \r
558                 /* CMD buff */\r
559                 rga_write(virt_to_phys(rga_service.cmd_buff) & (~PAGE_MASK), RGA_CMD_ADDR);               \r
560 \r
561                 /* master mode */\r
562                 rga_write(0x1<<2, RGA_SYS_CTRL);\r
563                                                               \r
564                 /* All CMD finish int */\r
565                 rga_write((0x1<<10)|(0x1<<8), RGA_INT);\r
566                                                 \r
567                 /* Start proc */\r
568                 atomic_set(&reg->session->done, 0);\r
569                 rga_write(0x1, RGA_CMD_CTRL);\r
570                 //rga_write(0x1<<1, RGA_SYS_CTRL);\r
571 \r
572                 #if RGA_TEST\r
573                 {\r
574                     uint32_t i;\r
575                     printk("CMD_READ_BACK_REG\n");\r
576                     for (i=0; i<7; i++)                    \r
577                         printk("%.8x %.8x %.8x %.8x\n", rga_read(0x100 + i*16 + 0), \r
578                                rga_read(0x100 + i*16 + 4), rga_read(0x100 + i*16 + 8), rga_read(0x100 + i*16 + 12));                    \r
579                 }\r
580                 #endif\r
581             }\r
582             num--;\r
583         }\r
584         while(0);\r
585         }\r
586         spin_unlock_irqrestore(&rga_service.lock, flag);\r
587 \r
588     \r
589 }\r
590 \r
591 \r
592 #if RGA_TEST  \r
593 static void print_info(struct rga_req *req)\r
594 {      \r
595     printk("src.yrgb_addr = %.8x, src.uv_addr = %.8x, src.v_addr = %.8x\n", \r
596             req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr);\r
597     printk("src : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", \r
598         req->src.act_w, req->src.act_h, req->src.vir_w, req->src.vir_h);\r
599     printk("src : x_offset = %.8x y_offset = %.8x\n", req->src.x_offset, req->src.y_offset);\r
600     \r
601     printk("dst.yrgb_addr = %.8x, dst.uv_addr = %.8x, dst.v_addr = %.8x\n", \r
602             req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr); \r
603     printk("dst : x_offset = %.8x y_offset = %.8x\n", req->dst.x_offset, req->dst.y_offset);\r
604     printk("dst : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", \r
605         req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h);\r
606 \r
607     printk("clip.xmin = %d, clip.xmax = %d. clip.ymin = %d, clip.ymax = %d\n", \r
608         req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax);   \r
609 }\r
610 #endif\r
611 \r
612 \r
613 static void rga_del_running_list(void)\r
614 {\r
615     struct rga_reg *reg;\r
616     \r
617     while(!list_empty(&rga_service.running))\r
618     {\r
619         reg = list_entry(rga_service.running.next, struct rga_reg, status_link);\r
620 \r
621         if(reg->MMU_base != NULL)\r
622         {\r
623             kfree(reg->MMU_base);\r
624         }\r
625                 \r
626         atomic_sub(1, &reg->session->task_running);\r
627             atomic_sub(1, &rga_service.total_running);\r
628         \r
629         if(list_empty(&reg->session->waiting))\r
630         {\r
631             atomic_set(&reg->session->done, 1);\r
632             wake_up_interruptible_sync(&reg->session->wait);\r
633         }\r
634         \r
635         rga_reg_deinit(reg);        \r
636     }    \r
637 }\r
638 \r
639 \r
640 static int rga_blit(rga_session *session, struct rga_req *req)\r
641 {\r
642     int ret = -1;\r
643     int num = 0; \r
644     struct rga_reg *reg;\r
645     struct rga_req *req2;\r
646 \r
647     uint32_t saw, sah, daw, dah;\r
648 \r
649     req2 = NULL;    \r
650                   \r
651     saw = req->src.act_w;\r
652     sah = req->src.act_h;\r
653     daw = req->dst.act_w;\r
654     dah = req->dst.act_h;\r
655 \r
656     do\r
657     {                \r
658         if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) \r
659         {                                   \r
660             /* generate 2 cmd for pre scale */        \r
661             req2 = kmalloc(sizeof(struct rga_req), GFP_KERNEL);\r
662             if(NULL == req2) {\r
663                 return -EFAULT;            \r
664             }\r
665             \r
666             ret = RGA_gen_two_pro(req, req2);            \r
667             if(ret == -EINVAL) {\r
668                 break;\r
669             }\r
670 \r
671             ret = rga_check_param(req);\r
672                 if(ret == -EINVAL) {\r
673                 printk("req 1 argument is inval\n");\r
674                 break;\r
675                 }\r
676                                                          \r
677             ret = rga_check_param(req2);\r
678                 if(ret == -EINVAL) {\r
679                 printk("req 2 argument is inval\n");\r
680                 break;\r
681                 }\r
682 \r
683             reg = rga_reg_init_2(session, req, req2);\r
684             if(reg == NULL) {\r
685                 break;\r
686             }            \r
687             num = 2;\r
688         }\r
689         else \r
690         {\r
691             /* check value if legal */\r
692             ret = rga_check_param(req);\r
693                 if(ret == -EINVAL) {\r
694                 break;\r
695                 }\r
696            \r
697             reg = rga_reg_init(session, req);\r
698             if(reg == NULL) {\r
699                 break;\r
700             }            \r
701             num = 1;       \r
702         }        \r
703 \r
704         //rga_power_on();\r
705         atomic_set(&reg->int_enable, 1);        \r
706         rga_try_set_reg(num);\r
707         \r
708         return 0;         \r
709     }\r
710     while(0);\r
711     \r
712     if(NULL != req2)\r
713     {\r
714         kfree(req2);\r
715     }\r
716 \r
717     return -EFAULT;\r
718 }\r
719 \r
720 static int rga_blit_async(rga_session *session, struct rga_req *req)\r
721 {\r
722         int ret = -1;\r
723     \r
724     #if RGA_TEST\r
725     printk("*** rga_blit_async proc ***\n");\r
726     print_info(req);\r
727     #endif\r
728                   \r
729     ret = rga_blit(session, req);\r
730     \r
731     return ret;\r
732 }\r
733 \r
734 static int rga_blit_sync(rga_session *session, struct rga_req *req)\r
735 {\r
736     int ret = -1;\r
737     int ret_timeout = 0;\r
738        \r
739     #if RGA_TEST\r
740     printk("*** rga_blit_sync proc ***\n");\r
741     print_info(req);\r
742     #endif\r
743 \r
744     #if RGA_TEST_TIME\r
745     rga_start = ktime_get();\r
746     #endif \r
747                      \r
748     ret = rga_blit(session, req);\r
749         \r
750     ret_timeout = wait_event_interruptible_timeout(session->wait, atomic_read(&session->done), RGA_TIMEOUT_DELAY);\r
751     \r
752     if (unlikely(ret_timeout< 0)) \r
753     {\r
754                 pr_err("sync pid %d wait task ret %d\n", session->pid, ret_timeout);        \r
755         rga_soft_reset();\r
756         ret = -ETIMEDOUT;\r
757         } \r
758     else if (0 == ret_timeout)\r
759     {\r
760                 pr_err("sync pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));\r
761         rga_soft_reset();\r
762                 ret = -ETIMEDOUT;\r
763         }\r
764 \r
765     #if RGA_TEST_TIME\r
766     rga_end = ktime_get();\r
767     rga_end = ktime_sub(rga_end, rga_start);\r
768     printk("sync one cmd end time %d\n", (int)ktime_to_us(rga_end));\r
769     #endif\r
770             \r
771     return ret;   \r
772 }\r
773 \r
774 \r
775 static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)\r
776 {\r
777     struct rga_req *req;\r
778         int ret = 0;\r
779     rga_session *session = (rga_session *)file->private_data;\r
780     \r
781         if (NULL == session) \r
782     {\r
783         printk("%s [%d] rga thread session is null\n",__FUNCTION__,__LINE__);\r
784                 return -EINVAL;\r
785         }\r
786 \r
787     mutex_lock(&rga_service.mutex);\r
788      \r
789     req = (struct rga_req *)kmalloc(sizeof(struct rga_req), GFP_KERNEL);\r
790     if(req == NULL) \r
791     {\r
792         printk("%s [%d] get rga_req mem failed\n",__FUNCTION__,__LINE__);\r
793         mutex_unlock(&rga_service.mutex);\r
794         return -EINVAL;\r
795     }\r
796            \r
797         switch (cmd)\r
798         {\r
799                 case RGA_BLIT_SYNC:\r
800                 if (unlikely(copy_from_user(req, (struct rga_req*)arg, sizeof(struct rga_req)))) \r
801             {\r
802                         ERR("copy_from_user failed\n");\r
803                         ret = -EFAULT;\r
804                 break;\r
805                 }\r
806             rga_power_on();\r
807             ret = rga_blit_sync(session, req);\r
808             break;\r
809                 case RGA_BLIT_ASYNC:\r
810                 if (unlikely(copy_from_user(req, (struct rga_req*)arg, sizeof(struct rga_req)))) \r
811             {\r
812                         ERR("copy_from_user failed\n");\r
813                         ret = -EFAULT;\r
814                 break;\r
815                 }\r
816             rga_power_on();\r
817                         ret = rga_blit_async(session, req);              \r
818                         break;\r
819                 case RGA_FLUSH:\r
820                         ret = rga_flush(session, arg);\r
821                         break;\r
822         case RGA_GET_RESULT:\r
823             ret = rga_get_result(session, arg);\r
824                 default:\r
825                         ERR("unknown ioctl cmd!\n");\r
826                         ret = -EINVAL;\r
827                         break;\r
828         }\r
829 \r
830     if(req != NULL) {\r
831         kfree(req);\r
832     }\r
833         \r
834     mutex_unlock(&rga_service.mutex);\r
835         \r
836         return ret;\r
837 }\r
838 \r
839 static int rga_open(struct inode *inode, struct file *file)\r
840 {\r
841     rga_session *session = (rga_session *)kmalloc(sizeof(rga_session), GFP_KERNEL);\r
842         if (NULL == session) {\r
843                 pr_err("unable to allocate memory for rga_session.");\r
844                 return -ENOMEM;\r
845         }\r
846 \r
847         session->pid    = current->pid;\r
848         INIT_LIST_HEAD(&session->waiting);\r
849         INIT_LIST_HEAD(&session->running);\r
850         INIT_LIST_HEAD(&session->list_session);\r
851         init_waitqueue_head(&session->wait);\r
852         /* no need to protect */\r
853         list_add_tail(&session->list_session, &rga_service.session);\r
854         atomic_set(&session->task_running, 0);\r
855     atomic_set(&session->num_done, 0);\r
856         file->private_data = (void *)session;\r
857 \r
858     DBG("*** rga dev opened by pid %d *** \n", session->pid);    \r
859         return nonseekable_open(inode, file);\r
860     \r
861 }\r
862 \r
863 static int rga_release(struct inode *inode, struct file *file)\r
864 {\r
865     int task_running;\r
866         unsigned long flag;\r
867         rga_session *session = (rga_session *)file->private_data;\r
868         if (NULL == session)\r
869                 return -EINVAL;\r
870     \r
871         task_running = atomic_read(&session->task_running);\r
872 \r
873     if (task_running) \r
874     {\r
875                 pr_err("rga_service session %d still has %d task running when closing\n", session->pid, task_running);\r
876                 msleep(100);\r
877         /*ͬ²½*/        \r
878         }\r
879     \r
880         wake_up_interruptible_sync(&session->wait);\r
881         spin_lock_irqsave(&rga_service.lock, flag);\r
882         list_del(&session->list_session);\r
883         rga_service_session_clear(session);\r
884         kfree(session);\r
885         spin_unlock_irqrestore(&rga_service.lock, flag);\r
886 \r
887     DBG("*** rga dev close ***\n");\r
888         return 0;\r
889 }\r
890 \r
891 static irqreturn_t rga_irq(int irq,  void *dev_id)\r
892 {\r
893     //struct rga_reg *reg;\r
894     uint32_t flag;\r
895     uint32_t i = 0;\r
896     //int int_enable = 0;\r
897     \r
898     #if RGA_TEST\r
899     printk("rga_irq is valid\n");\r
900     #endif\r
901 \r
902     if(rga_read(RGA_INT) & 0x1)\r
903     {\r
904         printk("bus Error interrupt is occur\n");\r
905     }\r
906    \r
907     while(((rga_read(RGA_STATUS) & 0x1) != 0) && (i<10))// idle\r
908         {       \r
909                 mdelay(1);\r
910         i++;\r
911         }    \r
912 \r
913      /*clear INT */\r
914         rga_write(rga_read(RGA_INT) | (0x1<<6) | (0x1<<7) | (0x1<<4), RGA_INT);\r
915     spin_lock_irqsave(&rga_service.lock, flag);\r
916     rga_del_running_list();\r
917     spin_unlock_irqrestore(&rga_service.lock, flag);\r
918        \r
919     if(!list_empty(&rga_service.waiting))\r
920     {\r
921         rga_try_set_reg(1);\r
922     }\r
923    \r
924     /* add cmd to cmd buf */\r
925     /*\r
926     while((!list_empty(next)) && ((int_enable) == 0) && (num <= 0xf))\r
927     {        \r
928         num += 1;\r
929         reg = list_entry(next->next, struct rga_reg, status_link);\r
930         int_enable = atomic_read(&reg->int_enable);        \r
931         next = next->next;\r
932     } \r
933     */\r
934                         \r
935         return IRQ_HANDLED;\r
936 }\r
937 \r
938 static int rga_suspend(struct platform_device *pdev, pm_message_t state)\r
939 {\r
940         uint32_t enable;\r
941     \r
942     enable = rga_service.enable;    \r
943         rga_power_off();\r
944     rga_service.enable = enable;\r
945 \r
946         return 0;\r
947 }\r
948 \r
949 static int rga_resume(struct platform_device *pdev)\r
950 {    \r
951     if(rga_service.enable)\r
952     {\r
953         rga_service.enable = false;\r
954         rga_power_on();\r
955         rga_try_set_reg(1);\r
956     }\r
957     \r
958         return 0;\r
959 }\r
960 \r
961 static void rga_shutdown(struct platform_device *pdev)\r
962 {\r
963         pr_cont("shutdown...");     \r
964         rga_power_off();    \r
965     pr_cont("done\n");\r
966 }\r
967 \r
968 struct file_operations rga_fops = {\r
969         .owner          = THIS_MODULE,\r
970         .open           = rga_open,\r
971         .release        = rga_release,\r
972         .unlocked_ioctl         = rga_ioctl,\r
973 };\r
974 \r
975 static struct miscdevice rga_dev ={\r
976     .minor = RGA_MAJOR,\r
977     .name  = "rga",\r
978     .fops  = &rga_fops,\r
979 };\r
980 \r
981 static int __devinit rga_drv_probe(struct platform_device *pdev)\r
982 {\r
983         struct rga_drvdata *data;\r
984         int ret = 0;\r
985 \r
986         data = kmalloc(sizeof(struct rga_drvdata), GFP_KERNEL);\r
987 \r
988     memset(data, 0x0, sizeof(struct rga_drvdata));\r
989 \r
990     INIT_LIST_HEAD(&rga_service.waiting);\r
991         INIT_LIST_HEAD(&rga_service.running);\r
992         INIT_LIST_HEAD(&rga_service.done);\r
993         INIT_LIST_HEAD(&rga_service.session);\r
994         spin_lock_init(&rga_service.lock);\r
995     atomic_set(&rga_service.total_running, 0);\r
996     atomic_set(&rga_service.src_format_swt, 0);\r
997     rga_service.last_prc_src_format = 1; /* default is yuv first*/\r
998     rga_service.enable = false;\r
999           \r
1000         if(NULL == data)\r
1001         {\r
1002                 ERR("failed to allocate driver data.\n");\r
1003                 return  -ENOMEM;\r
1004         }\r
1005         \r
1006         aclk_rga = clk_get(NULL, "aclk_rga");    \r
1007         if (IS_ERR(aclk_rga))\r
1008         {\r
1009                 ERR("failed to find rga axi clock source.\n");\r
1010                 ret = -ENOENT;\r
1011                 goto err_clock;\r
1012         }\r
1013 \r
1014         hclk_rga = clk_get(NULL, "hclk_rga");\r
1015         if (IS_ERR(hclk_rga))\r
1016         {\r
1017                 ERR("failed to find rga ahb clock source.\n");\r
1018                 ret = -ENOENT;\r
1019                 goto err_clock;\r
1020         }\r
1021 \r
1022     rga_power_on();\r
1023     \r
1024         /* map the memory */\r
1025     if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io")) \r
1026     {\r
1027                 pr_info("failed to reserve rga HW regs\n");\r
1028                 return -EBUSY;\r
1029         }\r
1030         data->rga_base = (void*)ioremap_nocache(RK30_RGA_PHYS, RK30_RGA_SIZE);\r
1031         if (data->rga_base == NULL)\r
1032         {\r
1033                 ERR("rga ioremap failed\n");\r
1034                 ret = -ENOENT;\r
1035                 goto err_ioremap;\r
1036         }\r
1037 \r
1038         /* get the IRQ */\r
1039         data->irq0 = pdev->resource[1].start;\r
1040         printk("rga irq %d\n", data->irq0);\r
1041         if (data->irq0 <= 0)\r
1042         {\r
1043                 ERR("failed to get rga irq resource (%d).\n", data->irq0);\r
1044                 ret = data->irq0;\r
1045                 goto err_irq;\r
1046         }\r
1047 \r
1048         /* request the IRQ */\r
1049         ret = request_irq(data->irq0, rga_irq, 0/*IRQF_DISABLED*/, "rga", pdev);\r
1050         if (ret)\r
1051         {\r
1052                 ERR("rga request_irq failed (%d).\n", ret);\r
1053                 goto err_irq;\r
1054         }\r
1055 \r
1056         mutex_init(&rga_service.mutex);\r
1057         rga_service.enable = false;\r
1058         INIT_DELAYED_WORK(&data->power_off_work, rga_power_off);\r
1059         data->rga_irq_callback = NULL;\r
1060         \r
1061         platform_set_drvdata(pdev, data);\r
1062         drvdata = data;\r
1063     \r
1064         ret = misc_register(&rga_dev);\r
1065         if(ret)\r
1066         {\r
1067                 ERR("cannot register miscdev (%d)\n", ret);\r
1068                 goto err_misc_register;\r
1069         }\r
1070 \r
1071     rga_power_off();\r
1072     \r
1073         DBG("RGA Driver loaded succesfully\n");\r
1074 \r
1075         return 0;    \r
1076 \r
1077 err_misc_register:\r
1078         free_irq(data->irq0, pdev);\r
1079 err_irq:\r
1080         iounmap(data->rga_base);\r
1081 err_ioremap:\r
1082 err_clock:\r
1083         kfree(data);\r
1084 \r
1085         return ret;\r
1086 }\r
1087 \r
1088 static int rga_drv_remove(struct platform_device *pdev)\r
1089 {\r
1090         struct rga_drvdata *data = platform_get_drvdata(pdev);\r
1091     DBG("%s [%d]\n",__FUNCTION__,__LINE__);\r
1092 \r
1093     misc_deregister(&(data->miscdev));\r
1094         free_irq(data->irq0, &data->miscdev);\r
1095     iounmap((void __iomem *)(data->rga_base));            \r
1096 \r
1097     if(aclk_rga) {\r
1098                 clk_put(aclk_rga);\r
1099         }\r
1100         \r
1101         if(hclk_rga) {\r
1102                 clk_put(hclk_rga);\r
1103         }\r
1104 \r
1105     kfree(data);\r
1106     return 0;\r
1107 }\r
1108 \r
1109 static struct platform_driver rga_driver = {\r
1110         .probe          = rga_drv_probe,\r
1111         .remove         = __devexit_p(rga_drv_remove),\r
1112         .suspend    = rga_suspend,\r
1113         .resume     = rga_resume,\r
1114         .shutdown   = rga_shutdown,\r
1115         .driver         = {\r
1116                 .owner  = THIS_MODULE,\r
1117                 .name   = "rga",\r
1118         },\r
1119 };\r
1120 \r
1121 \r
1122 void rga_test_0(void);\r
1123 \r
1124 \r
1125 static int __init rga_init(void)\r
1126 {\r
1127         int ret;\r
1128     uint32_t *mmu_buf;\r
1129     uint32_t i;\r
1130     uint32_t *buf_p;\r
1131 \r
1132     /* malloc pre scale mid buf mmu table */\r
1133     mmu_buf = (uint32_t *)kmalloc(1024*8, GFP_KERNEL);    \r
1134     if(mmu_buf == NULL) \r
1135     {\r
1136         printk(KERN_ERR "RGA get Pre Scale buff failed. \n");\r
1137         return -1;\r
1138     }\r
1139 \r
1140     /* malloc 8 M buf */\r
1141     for(i=0; i<2048; i++)\r
1142     {        \r
1143         buf_p = (uint32_t *)__get_free_page(GFP_KERNEL);               \r
1144         if(buf_p == NULL)\r
1145         {\r
1146             printk(KERN_ERR "RGA init pre scale buf falied\n");\r
1147             return -ENOMEM;\r
1148         }\r
1149         \r
1150         mmu_buf[i] = virt_to_phys((void *)((uint32_t)buf_p));        \r
1151     }\r
1152         \r
1153     rga_service.pre_scale_buf = (uint32_t *)mmu_buf;    \r
1154 \r
1155         if ((ret = platform_driver_register(&rga_driver)) != 0)\r
1156         {\r
1157         printk(KERN_ERR "Platform device register failed (%d).\n", ret);\r
1158                         return ret;\r
1159         }\r
1160 \r
1161     //rga_test_0();\r
1162     \r
1163         INFO("Module initialized.\n");  \r
1164     \r
1165         return 0;\r
1166 }\r
1167 \r
1168 static void __exit rga_exit(void)\r
1169 {\r
1170     uint32_t i;\r
1171 \r
1172     rga_power_off();\r
1173 \r
1174     for(i=0; i<2048; i++)\r
1175     {\r
1176         if((uint32_t *)rga_service.pre_scale_buf[i] != NULL)\r
1177         {\r
1178             __free_page((void *)rga_service.pre_scale_buf[i]);\r
1179         }        \r
1180     }\r
1181     \r
1182     if(rga_service.pre_scale_buf != NULL) {\r
1183         kfree((uint8_t *)rga_service.pre_scale_buf);\r
1184     }\r
1185         platform_driver_unregister(&rga_driver); \r
1186 }\r
1187 \r
1188 \r
1189 #if 0\r
1190 \r
1191 #include "320x240_swap0_Y4200.h"\r
1192 #include "320x240_swap0_U4200.h"\r
1193 #include "320x240_swap0_V4200.h"\r
1194 #include "320x240_swap0_UV4200.h"\r
1195 #include "320x240_swap0_ABGR8888.h"\r
1196 \r
1197 \r
1198 extern struct fb_info * rk_get_fb(int fb_id);\r
1199 EXPORT_SYMBOL(rk_get_fb);\r
1200 \r
1201 extern void rk_direct_fb_show(struct fb_info * fbi);\r
1202 EXPORT_SYMBOL(rk_direct_fb_show);\r
1203 \r
1204 unsigned int src_buf[1920*1080];\r
1205 unsigned int dst_buf[1280*800];\r
1206 \r
1207 void rga_test_0(void)\r
1208 {\r
1209     struct rga_req req;\r
1210     rga_session session;\r
1211     unsigned int *src, *dst;\r
1212 \r
1213     struct fb_info *fb;\r
1214 \r
1215     session.pid = current->pid;\r
1216         INIT_LIST_HEAD(&session.waiting);\r
1217         INIT_LIST_HEAD(&session.running);\r
1218         INIT_LIST_HEAD(&session.list_session);\r
1219         init_waitqueue_head(&session.wait);\r
1220         /* no need to protect */\r
1221         list_add_tail(&session.list_session, &rga_service.session);\r
1222         atomic_set(&session.task_running, 0);\r
1223     atomic_set(&session.num_done, 0);\r
1224         //file->private_data = (void *)session;\r
1225 \r
1226     fb = rk_get_fb(0);\r
1227 \r
1228     memset(&req, 0, sizeof(struct rga_req));\r
1229     src = src_buf;\r
1230     dst = dst_buf;\r
1231 \r
1232     memset(src_buf, 0x80, 1920*1080*4);\r
1233 \r
1234     dmac_flush_range(&src_buf[0], &src_buf[1920*1080]);\r
1235     outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*1024]));\r
1236         \r
1237     #if 0\r
1238     memset(src_buf, 0x80, 800*480*4);\r
1239     memset(dst_buf, 0xcc, 800*480*4);\r
1240         \r
1241     dmac_flush_range(&dst_buf[0], &dst_buf[800*480]);\r
1242     outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480]));\r
1243     #endif\r
1244    \r
1245     req.src.act_w = 1920;\r
1246     req.src.act_h = 1080;\r
1247 \r
1248     req.src.vir_w = 1920;\r
1249     req.src.vir_h = 1080;\r
1250     req.src.yrgb_addr = (uint32_t)src_buf;\r
1251     req.src.uv_addr = req.src.yrgb_addr + 1920;\r
1252     //req.src.v_addr = (uint32_t)V4200_320_240_swap0;\r
1253     req.src.format = RK_FORMAT_YCbCr_420_SP;\r
1254 \r
1255     req.dst.act_w = 1280;\r
1256     req.dst.act_h = 736;\r
1257 \r
1258     req.dst.vir_w = 1280;\r
1259     req.dst.vir_h = 736;\r
1260     req.dst.x_offset = 0;\r
1261     req.dst.y_offset = 0;\r
1262     req.dst.yrgb_addr = (uint32_t)dst;\r
1263 \r
1264     //req.dst.format = RK_FORMAT_RGB_565;\r
1265 \r
1266     req.clip.xmin = 0;\r
1267     req.clip.xmax = 1279;\r
1268     req.clip.ymin = 0;\r
1269     req.clip.ymax = 799;\r
1270 \r
1271     //req.render_mode = color_fill_mode;\r
1272     //req.fg_color = 0x80ffffff;\r
1273             \r
1274     req.rotate_mode = 1;\r
1275     req.scale_mode = 0;\r
1276 \r
1277     req.alpha_rop_flag = 0;\r
1278     req.alpha_rop_mode = 0x1;\r
1279 \r
1280     req.sina = 0;\r
1281     req.cosa = 65536;\r
1282 \r
1283     req.mmu_info.mmu_flag = 0x21;\r
1284     req.mmu_info.mmu_en = 1;\r
1285 \r
1286     rga_blit_sync(&session, &req);\r
1287 \r
1288     fb->var.bits_per_pixel = 32;\r
1289 \r
1290     fb->var.xres = 1280;\r
1291     fb->var.yres = 800;\r
1292     \r
1293     fb->var.red.length = 8;\r
1294     fb->var.red.offset = 0;\r
1295     fb->var.red.msb_right = 0;\r
1296     \r
1297     fb->var.green.length = 8;\r
1298     fb->var.green.offset = 8;\r
1299     fb->var.green.msb_right = 0;\r
1300     \r
1301     fb->var.blue.length = 8;\r
1302     \r
1303     fb->var.blue.offset = 16;\r
1304     fb->var.blue.msb_right = 0;\r
1305     \r
1306     fb->var.transp.length = 8;\r
1307     fb->var.transp.offset = 24;\r
1308     fb->var.transp.msb_right = 0;\r
1309 \r
1310     fb->var.nonstd &= (~0xff);\r
1311     fb->var.nonstd |= 1;\r
1312 \r
1313     fb->fix.smem_start = virt_to_phys(dst);\r
1314 \r
1315     rk_direct_fb_show(fb);   \r
1316     \r
1317 }\r
1318 \r
1319 #endif\r
1320 module_init(rga_init);\r
1321 module_exit(rga_exit);\r
1322 \r
1323 /* Module information */\r
1324 MODULE_AUTHOR("zsq@rock-chips.com");\r
1325 MODULE_DESCRIPTION("Driver for rga device");\r
1326 MODULE_LICENSE("GPL");\r