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