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