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