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