rga: refactor rga_drv.c for support rk30/rk31/rk2928
[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 #if defined(CONFIG_ARCH_RK2928)\r
64 #define RK30_RGA_PHYS           RK2928_RGA_PHYS\r
65 #define RK30_RGA_SIZE           RK2928_RGA_SIZE\r
66 #endif\r
67 #define RGA_RESET_TIMEOUT       1000\r
68 \r
69 /* Driver information */\r
70 #define DRIVER_DESC             "RGA Device Driver"\r
71 #define DRIVER_NAME             "rga"\r
72 \r
73 #define RGA_VERSION   "1.000"\r
74 \r
75 ktime_t rga_start;\r
76 ktime_t rga_end;\r
77 \r
78 int rga_num = 0;\r
79 \r
80 struct rga_drvdata {\r
81         struct miscdevice miscdev;\r
82         struct device dev;\r
83         void *rga_base;\r
84         int irq;\r
85 \r
86         struct delayed_work power_off_work;\r
87         void (*rga_irq_callback)(int rga_retval);   //callback function used by aync call\r
88         struct wake_lock wake_lock;\r
89 \r
90         struct clk *aclk_rga;\r
91         struct clk *hclk_rga;\r
92         struct clk *pd_rga;\r
93 };\r
94 \r
95 static struct rga_drvdata *drvdata;\r
96 rga_service_info rga_service;\r
97 \r
98 static int rga_blit_async(rga_session *session, struct rga_req *req);\r
99 static void rga_del_running_list(void);\r
100 static void rga_del_running_list_timeout(void);\r
101 static void rga_try_set_reg(void);\r
102 \r
103 \r
104 /* Logging */\r
105 #define RGA_DEBUG 0\r
106 #if RGA_DEBUG\r
107 #define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args)\r
108 #define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args)\r
109 #define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args)\r
110 #define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args)\r
111 #else\r
112 #define DBG(format, args...)\r
113 #define ERR(format, args...)\r
114 #define WARNING(format, args...)\r
115 #define INFO(format, args...)\r
116 #endif\r
117 \r
118 \r
119 static inline void rga_write(u32 b, u32 r)\r
120 {\r
121         __raw_writel(b, drvdata->rga_base + r);\r
122 }\r
123 \r
124 static inline u32 rga_read(u32 r)\r
125 {\r
126         return __raw_readl(drvdata->rga_base + r);\r
127 }\r
128 \r
129 static void rga_soft_reset(void)\r
130 {\r
131         u32 i;\r
132         u32 reg;\r
133 \r
134         rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL\r
135 \r
136         for(i = 0; i < RGA_RESET_TIMEOUT; i++)\r
137         {\r
138                 reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL\r
139 \r
140                 if(reg == 0)\r
141                         break;\r
142 \r
143                 udelay(1);\r
144         }\r
145 \r
146         if(i == RGA_RESET_TIMEOUT)\r
147                 ERR("soft reset timeout.\n");\r
148 }\r
149 \r
150 static void rga_dump(void)\r
151 {\r
152         int running;\r
153     struct rga_reg *reg, *reg_tmp;\r
154     rga_session *session, *session_tmp;\r
155 \r
156         running = atomic_read(&rga_service.total_running);\r
157         printk("rga total_running %d\n", running);\r
158 \r
159     #if 0\r
160 \r
161     /* Dump waiting list info */\r
162     if (!list_empty(&rga_service.waiting))\r
163     {\r
164         next = &rga_service.waiting;\r
165 \r
166         printk("rga_service dump waiting list\n");\r
167 \r
168         do\r
169         {\r
170             reg = list_entry(next->next, struct rga_reg, status_link);\r
171             running = atomic_read(&reg->session->task_running);\r
172             num_done = atomic_read(&reg->session->num_done);\r
173             printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running);\r
174             next = next->next;\r
175         }\r
176         while(!list_empty(next));\r
177     }\r
178 \r
179     /* Dump running list info */\r
180     if (!list_empty(&rga_service.running))\r
181     {\r
182         printk("rga_service dump running list\n");\r
183 \r
184         next = &rga_service.running;\r
185         do\r
186         {\r
187             reg = list_entry(next->next, struct rga_reg, status_link);\r
188             running = atomic_read(&reg->session->task_running);\r
189             num_done = atomic_read(&reg->session->num_done);\r
190             printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running);\r
191             next = next->next;\r
192         }\r
193         while(!list_empty(next));\r
194     }\r
195     #endif\r
196 \r
197         list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session)\r
198     {\r
199                 printk("session pid %d:\n", session->pid);\r
200                 running = atomic_read(&session->task_running);\r
201                 printk("task_running %d\n", running);\r
202                 list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link)\r
203         {\r
204                         printk("waiting register set 0x%.8x\n", (unsigned int)reg);\r
205                 }\r
206                 list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link)\r
207         {\r
208                         printk("running register set 0x%.8x\n", (unsigned int)reg);\r
209                 }\r
210         }\r
211 }\r
212 \r
213 /* Caller must hold rga_service.lock */\r
214 static void rga_power_on(void)\r
215 {\r
216         cancel_delayed_work_sync(&drvdata->power_off_work);\r
217         queue_delayed_work(system_nrt_wq, &drvdata->power_off_work, RGA_POWER_OFF_DELAY);\r
218         if (rga_service.enable)\r
219                 return;\r
220 \r
221         clk_enable(drvdata->aclk_rga);\r
222         clk_enable(drvdata->hclk_rga);\r
223         clk_enable(drvdata->pd_rga);\r
224         wake_lock(&drvdata->wake_lock);\r
225         rga_service.enable = true;\r
226 }\r
227 \r
228 /* Caller must hold rga_service.lock */\r
229 static void rga_power_off(void)\r
230 {\r
231         int total_running;\r
232 \r
233         if (!rga_service.enable) {\r
234                 return;\r
235         }\r
236 \r
237         total_running = atomic_read(&rga_service.total_running);\r
238         if (total_running) {\r
239                 pr_err("power off when %d task running!!\n", total_running);\r
240                 mdelay(50);\r
241                 pr_err("delay 50 ms for running task\n");\r
242                 rga_dump();\r
243         }\r
244 \r
245         clk_disable(drvdata->pd_rga);\r
246         clk_disable(drvdata->aclk_rga);\r
247         clk_disable(drvdata->hclk_rga);\r
248         wake_unlock(&drvdata->wake_lock);\r
249         rga_service.enable = false;\r
250 }\r
251 \r
252 static void rga_power_off_work(struct work_struct *work)\r
253 {\r
254         mutex_lock(&rga_service.lock);\r
255         rga_power_off();\r
256         mutex_unlock(&rga_service.lock);\r
257 }\r
258 \r
259 static int rga_flush(rga_session *session, unsigned long arg)\r
260 {\r
261     int ret = 0;\r
262     int ret_timeout;\r
263 \r
264     #if RGA_TEST_FLUSH_TIME\r
265     ktime_t start;\r
266     ktime_t end;\r
267     start = ktime_get();\r
268     #endif\r
269 \r
270     ret_timeout = wait_event_interruptible_timeout(session->wait, atomic_read(&session->done), RGA_TIMEOUT_DELAY);\r
271 \r
272         if (unlikely(ret_timeout < 0)) {\r
273                 pr_err("flush pid %d wait task ret %d\n", session->pid, ret);\r
274         mutex_lock(&rga_service.lock);\r
275         rga_del_running_list();\r
276         mutex_unlock(&rga_service.lock);\r
277         ret = -ETIMEDOUT;\r
278         } else if (0 == ret_timeout) {\r
279                 pr_err("flush pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));\r
280         printk("bus  = %.8x\n", rga_read(RGA_INT));\r
281         mutex_lock(&rga_service.lock);\r
282         rga_del_running_list_timeout();\r
283         rga_try_set_reg();\r
284         mutex_unlock(&rga_service.lock);\r
285                 ret = -ETIMEDOUT;\r
286         }\r
287 \r
288     #if RGA_TEST_FLUSH_TIME\r
289     end = ktime_get();\r
290     end = ktime_sub(end, start);\r
291     printk("one flush wait time %d\n", (int)ktime_to_us(end));\r
292     #endif\r
293 \r
294         return ret;\r
295 }\r
296 \r
297 \r
298 static int rga_get_result(rga_session *session, unsigned long arg)\r
299 {\r
300         //printk("rga_get_result %d\n",drvdata->rga_result);\r
301 \r
302     int ret = 0;\r
303 \r
304     int num_done;\r
305 \r
306     num_done = atomic_read(&session->num_done);\r
307 \r
308         if (unlikely(copy_to_user((void __user *)arg, &num_done, sizeof(int)))) {\r
309                         printk("copy_to_user failed\n");\r
310                         ERR("copy_to_user failed\n");\r
311                         ret =  -EFAULT;\r
312                 }\r
313         return ret;\r
314 }\r
315 \r
316 \r
317 static int rga_check_param(const struct rga_req *req)\r
318 {\r
319         /*RGA can support up to 8192*8192 resolution in RGB format,but we limit the image size to 8191*8191 here*/\r
320         //check src width and height\r
321 \r
322     if(!((req->render_mode == color_fill_mode) || (req->render_mode == line_point_drawing_mode)))\r
323     {\r
324         if (unlikely((req->src.act_w <= 0) || (req->src.act_w > 8191) || (req->src.act_h <= 0) || (req->src.act_h > 8191)))\r
325         {\r
326                 ERR("invalid source resolution act_w = %d, act_h = %d\n", req->src.act_w, req->src.act_h);\r
327                 return  -EINVAL;\r
328         }\r
329     }\r
330 \r
331     if(!((req->render_mode == color_fill_mode) || (req->render_mode == line_point_drawing_mode)))\r
332     {\r
333         if (unlikely((req->src.vir_w <= 0) || (req->src.vir_w > 8191) || (req->src.vir_h <= 0) || (req->src.vir_h > 8191)))\r
334         {\r
335                 ERR("invalid source resolution vir_w = %d, vir_h = %d\n", req->src.vir_w, req->src.vir_h);\r
336                 return  -EINVAL;\r
337         }\r
338     }\r
339 \r
340         //check dst width and height\r
341         if (unlikely((req->dst.act_w <= 0) || (req->dst.act_w > 2048) || (req->dst.act_h <= 0) || (req->dst.act_h > 2048)))\r
342     {\r
343                 ERR("invalid destination resolution act_w = %d, act_h = %d\n", req->dst.act_w, req->dst.act_h);\r
344                 return  -EINVAL;\r
345         }\r
346 \r
347     if (unlikely((req->dst.vir_w <= 0) || (req->dst.vir_w > 4096) || (req->dst.vir_h <= 0) || (req->dst.vir_h > 2048)))\r
348     {\r
349                 ERR("invalid destination resolution vir_w = %d, vir_h = %d\n", req->dst.vir_w, req->dst.vir_h);\r
350                 return  -EINVAL;\r
351         }\r
352 \r
353         //check src_vir_w\r
354         if(unlikely(req->src.vir_w < req->src.act_w)){\r
355                 ERR("invalid src_vir_w act_w = %d, vir_w = %d\n", req->src.act_w, req->src.vir_w);\r
356                 return  -EINVAL;\r
357         }\r
358 \r
359         //check dst_vir_w\r
360         if(unlikely(req->dst.vir_w < req->dst.act_w)){\r
361                 ERR("invalid dst_vir_w act_h = %d, vir_h = %d\n", req->dst.act_w, req->dst.vir_w);\r
362                 return  -EINVAL;\r
363         }\r
364 \r
365         return 0;\r
366 }\r
367 \r
368 static void rga_copy_reg(struct rga_reg *reg, uint32_t offset)\r
369 {\r
370     uint32_t i;\r
371     uint32_t *cmd_buf;\r
372     uint32_t *reg_p;\r
373 \r
374     if(atomic_read(&reg->session->task_running) != 0)\r
375     {\r
376         printk(KERN_ERR "task_running is no zero\n");\r
377     }\r
378 \r
379     atomic_add(1, &rga_service.cmd_num);\r
380         atomic_add(1, &reg->session->task_running);\r
381 \r
382     cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*28;\r
383     reg_p = (uint32_t *)reg->cmd_reg;\r
384 \r
385     for(i=0; i<28; i++)\r
386     {\r
387         cmd_buf[i] = reg_p[i];\r
388     }\r
389 \r
390     dsb();\r
391 }\r
392 \r
393 \r
394 static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req)\r
395 {\r
396     uint32_t ret;\r
397         struct rga_reg *reg = kzalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
398         if (NULL == reg) {\r
399                 pr_err("kmalloc fail in rga_reg_init\n");\r
400                 return NULL;\r
401         }\r
402 \r
403     reg->session = session;\r
404         INIT_LIST_HEAD(&reg->session_link);\r
405         INIT_LIST_HEAD(&reg->status_link);\r
406 \r
407     //memcpy(&reg->req, req, sizeof(struct rga_req));\r
408 \r
409     reg->MMU_base = NULL;\r
410 \r
411     if (req->mmu_info.mmu_en)\r
412     {\r
413         ret = rga_set_mmu_info(reg, req);\r
414         if(ret < 0)\r
415         {\r
416             printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
417             if(reg != NULL)\r
418             {\r
419                 kfree(reg);\r
420             }\r
421             return NULL;\r
422         }\r
423     }\r
424 \r
425     if(RGA_gen_reg_info(req, (uint8_t *)reg->cmd_reg) == -1)\r
426     {\r
427         printk("gen reg info error\n");\r
428         if(reg != NULL)\r
429         {\r
430             kfree(reg);\r
431         }\r
432         return NULL;\r
433     }\r
434 \r
435     mutex_lock(&rga_service.lock);\r
436         list_add_tail(&reg->status_link, &rga_service.waiting);\r
437         list_add_tail(&reg->session_link, &session->waiting);\r
438         mutex_unlock(&rga_service.lock);\r
439 \r
440     return reg;\r
441 }\r
442 \r
443 static struct rga_reg * rga_reg_init_2(rga_session *session, struct rga_req *req0, struct rga_req *req1)\r
444 {\r
445     uint32_t ret;\r
446 \r
447     struct rga_reg *reg0, *reg1;\r
448 \r
449     reg0 = NULL;\r
450     reg1 = NULL;\r
451 \r
452     do\r
453     {\r
454         reg0 = kzalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
455         if (NULL == reg0) {\r
456                 pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__);\r
457             break;\r
458         }\r
459 \r
460         reg1 = kzalloc(sizeof(struct rga_reg), GFP_KERNEL);\r
461         if (NULL == reg1) {\r
462                 pr_err("%s [%d] kmalloc fail in rga_reg_init\n", __FUNCTION__, __LINE__);\r
463             break;\r
464         }\r
465 \r
466         reg0->session = session;\r
467         INIT_LIST_HEAD(&reg0->session_link);\r
468         INIT_LIST_HEAD(&reg0->status_link);\r
469 \r
470         reg1->session = session;\r
471         INIT_LIST_HEAD(&reg1->session_link);\r
472         INIT_LIST_HEAD(&reg1->status_link);\r
473 \r
474         //memcpy(&reg0->req, req0, sizeof(struct rga_req));\r
475         //memcpy(&reg1->req, req1, sizeof(struct rga_req));\r
476 \r
477         if(req0->mmu_info.mmu_en)\r
478         {\r
479             ret = rga_set_mmu_info(reg0, req0);\r
480             if(ret < 0) {\r
481                 printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
482                 break;\r
483             }\r
484         }\r
485 \r
486         RGA_gen_reg_info(req0, (uint8_t *)reg0->cmd_reg);\r
487 \r
488         if(req1->mmu_info.mmu_en)\r
489         {\r
490             ret = rga_set_mmu_info(reg1, req1);\r
491             if(ret < 0) {\r
492                 printk("%s, [%d] set mmu info error \n", __FUNCTION__, __LINE__);\r
493                 break;\r
494             }\r
495         }\r
496 \r
497         RGA_gen_reg_info(req1, (uint8_t *)reg1->cmd_reg);\r
498 \r
499         mutex_lock(&rga_service.lock);\r
500         list_add_tail(&reg0->status_link, &rga_service.waiting);\r
501         list_add_tail(&reg0->session_link, &session->waiting);\r
502         list_add_tail(&reg1->status_link, &rga_service.waiting);\r
503         list_add_tail(&reg1->session_link, &session->waiting);\r
504         mutex_unlock(&rga_service.lock);\r
505 \r
506         return reg1;\r
507     }\r
508     while(0);\r
509 \r
510     if(reg0 != NULL) {\r
511         kfree(reg0);\r
512     }\r
513 \r
514     if(reg1 != NULL) {\r
515         kfree(reg1);\r
516     }\r
517 \r
518     return NULL;\r
519 }\r
520 \r
521 /* Caller must hold rga_service.lock */\r
522 static void rga_reg_deinit(struct rga_reg *reg)\r
523 {\r
524         list_del_init(&reg->session_link);\r
525         list_del_init(&reg->status_link);\r
526         kfree(reg);\r
527 }\r
528 \r
529 /* Caller must hold rga_service.lock */\r
530 static void rga_reg_from_wait_to_run(struct rga_reg *reg)\r
531 {\r
532         list_del_init(&reg->status_link);\r
533         list_add_tail(&reg->status_link, &rga_service.running);\r
534 \r
535         list_del_init(&reg->session_link);\r
536         list_add_tail(&reg->session_link, &reg->session->running);\r
537 }\r
538 \r
539 /* Caller must hold rga_service.lock */\r
540 static void rga_service_session_clear(rga_session *session)\r
541 {\r
542         struct rga_reg *reg, *n;\r
543 \r
544     list_for_each_entry_safe(reg, n, &session->waiting, session_link)\r
545     {\r
546                 rga_reg_deinit(reg);\r
547         }\r
548 \r
549     list_for_each_entry_safe(reg, n, &session->running, session_link)\r
550     {\r
551                 rga_reg_deinit(reg);\r
552         }\r
553 }\r
554 \r
555 /* Caller must hold rga_service.lock */\r
556 static void rga_try_set_reg(void)\r
557 {\r
558     struct rga_reg *reg ;\r
559 \r
560     if (list_empty(&rga_service.running))\r
561     {\r
562         if (!list_empty(&rga_service.waiting))\r
563         {\r
564             /* RGA is idle */\r
565             reg = list_entry(rga_service.waiting.next, struct rga_reg, status_link);\r
566 \r
567             rga_power_on();\r
568             udelay(1);\r
569 \r
570             rga_copy_reg(reg, 0);\r
571             rga_reg_from_wait_to_run(reg);\r
572 \r
573             dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[28]);\r
574             outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[28]));\r
575 \r
576             #if defined(CONFIG_ARCH_RK30)\r
577             rga_soft_reset();\r
578             #endif\r
579 \r
580             rga_write(0x0, RGA_SYS_CTRL);                        \r
581             rga_write(0, RGA_MMU_CTRL);\r
582 \r
583             /* CMD buff */\r
584             rga_write(virt_to_phys(rga_service.cmd_buff), RGA_CMD_ADDR);\r
585 \r
586 #if RGA_TEST\r
587             {\r
588                 //printk(KERN_DEBUG "cmd_addr = %.8x\n", rga_read(RGA_CMD_ADDR));\r
589                 uint32_t i;\r
590                 uint32_t *p;\r
591                 p = rga_service.cmd_buff;\r
592                 printk("CMD_REG\n");\r
593                 for (i=0; i<7; i++)\r
594                     printk("%.8x %.8x %.8x %.8x\n", p[0 + i*4], p[1+i*4], p[2 + i*4], p[3 + i*4]);\r
595             }\r
596 #endif\r
597 \r
598             /* master mode */\r
599             rga_write((0x1<<2)|(0x1<<3), RGA_SYS_CTRL);\r
600 \r
601             /* All CMD finish int */\r
602             rga_write(rga_read(RGA_INT)|(0x1<<10)|(0x1<<8), RGA_INT);\r
603 \r
604             /* Start proc */\r
605             atomic_set(&reg->session->done, 0);\r
606             rga_write(0x1, RGA_CMD_CTRL);\r
607 \r
608 #if RGA_TEST\r
609             {\r
610                 uint32_t i;\r
611                 printk("CMD_READ_BACK_REG\n");\r
612                 for (i=0; i<7; i++)\r
613                     printk("%.8x %.8x %.8x %.8x\n", rga_read(0x100 + i*16 + 0),\r
614                             rga_read(0x100 + i*16 + 4), rga_read(0x100 + i*16 + 8), rga_read(0x100 + i*16 + 12));\r
615             }\r
616 #endif\r
617         }\r
618     }\r
619 }\r
620 \r
621 \r
622 #if RGA_TEST\r
623 static void print_info(struct rga_req *req)\r
624 {\r
625     printk("src.yrgb_addr = %.8x, src.uv_addr = %.8x, src.v_addr = %.8x\n",\r
626             req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr);\r
627     printk("src : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n",\r
628         req->src.act_w, req->src.act_h, req->src.vir_w, req->src.vir_h);\r
629     printk("src : x_offset = %.8x y_offset = %.8x\n", req->src.x_offset, req->src.y_offset);\r
630 \r
631     printk("dst.yrgb_addr = %.8x, dst.uv_addr = %.8x, dst.v_addr = %.8x\n",\r
632             req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr);\r
633     printk("dst : x_offset = %.8x y_offset = %.8x\n", req->dst.x_offset, req->dst.y_offset);\r
634     printk("dst : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n",\r
635         req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h);\r
636 \r
637     printk("clip.xmin = %d, clip.xmax = %d. clip.ymin = %d, clip.ymax = %d\n",\r
638         req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax);\r
639 \r
640     printk("alpha_rop_flag = %.8x\n", req->alpha_rop_flag);\r
641     printk("alpha_rop_mode = %.8x\n", req->alpha_rop_mode);\r
642     printk("PD_mode = %.8x\n", req->PD_mode);\r
643 }\r
644 #endif\r
645 \r
646 /* Caller must hold rga_service.lock */\r
647 static void rga_del_running_list(void)\r
648 {\r
649     struct rga_reg *reg;\r
650 \r
651     while(!list_empty(&rga_service.running))\r
652     {\r
653         reg = list_entry(rga_service.running.next, struct rga_reg, status_link);\r
654 \r
655         if(reg->MMU_base != NULL)\r
656         {\r
657             kfree(reg->MMU_base);\r
658             reg->MMU_base = NULL;\r
659         }\r
660         atomic_sub(1, &reg->session->task_running);\r
661         atomic_sub(1, &rga_service.total_running);\r
662 \r
663         if(list_empty(&reg->session->waiting))\r
664         {\r
665             atomic_set(&reg->session->done, 1);\r
666             wake_up_interruptible_sync(&reg->session->wait);\r
667         }\r
668 \r
669         rga_reg_deinit(reg);\r
670     }\r
671 }\r
672 \r
673 /* Caller must hold rga_service.lock */\r
674 static void rga_del_running_list_timeout(void)\r
675 {\r
676     struct rga_reg *reg;\r
677 \r
678     while(!list_empty(&rga_service.running))\r
679     {\r
680         reg = list_entry(rga_service.running.next, struct rga_reg, status_link);\r
681 \r
682         if(reg->MMU_base != NULL)\r
683         {\r
684             kfree(reg->MMU_base);\r
685         }\r
686 \r
687         atomic_sub(1, &reg->session->task_running);\r
688         atomic_sub(1, &rga_service.total_running);\r
689 \r
690 \r
691         #if 0\r
692         printk("RGA_INT is %.8x\n", rga_read(RGA_INT));\r
693         printk("reg->session->task_running = %d\n", atomic_read(&reg->session->task_running));\r
694         printk("rga_service.total_running  = %d\n", atomic_read(&rga_service.total_running));\r
695 \r
696         print_info(&reg->req);\r
697 \r
698         {\r
699             uint32_t *p, i;\r
700             p = reg->cmd_reg;\r
701             for (i=0; i<7; i++)\r
702                 printk("%.8x %.8x %.8x %.8x\n", p[0 + i*4], p[1+i*4], p[2 + i*4], p[3 + i*4]);\r
703 \r
704         }\r
705         #endif\r
706 \r
707         if(list_empty(&reg->session->waiting))\r
708         {\r
709             atomic_set(&reg->session->done, 1);\r
710             wake_up_interruptible_sync(&reg->session->wait);\r
711         }\r
712 \r
713         rga_reg_deinit(reg);\r
714     }\r
715 }\r
716 \r
717 \r
718 static void rga_mem_addr_sel(struct rga_req *req)\r
719 {\r
720     switch(req->src.format)\r
721     {\r
722         case RK_FORMAT_YCbCr_422_SP:\r
723             break;\r
724         case RK_FORMAT_YCbCr_422_P :\r
725             break;\r
726         case RK_FORMAT_YCbCr_420_SP :\r
727             if((req->src.yrgb_addr > 0xc0000000) && (req->src.uv_addr > 0xc0000000)\r
728                 && (req->dst.yrgb_addr > 0xc0000000))\r
729             {\r
730                 req->src.yrgb_addr = req->src.yrgb_addr - 0x60000000;\r
731                 req->src.uv_addr = req->src.uv_addr - 0x60000000;\r
732                 req->dst.yrgb_addr = req->dst.yrgb_addr - 0x60000000;\r
733                 req->mmu_info.mmu_en = 0;\r
734                 req->mmu_info.mmu_flag &= 0xfffe;\r
735             }\r
736             break;\r
737         case RK_FORMAT_YCbCr_420_P :\r
738             break;\r
739         case RK_FORMAT_YCrCb_422_SP :\r
740             break;\r
741         case RK_FORMAT_YCrCb_422_P :\r
742             break;\r
743         case RK_FORMAT_YCrCb_420_SP :\r
744             break;\r
745         case RK_FORMAT_YCrCb_420_P :\r
746             break;\r
747         default :\r
748             break;\r
749     }\r
750 \r
751 }\r
752 \r
753 \r
754 static int rga_blit(rga_session *session, struct rga_req *req)\r
755 {\r
756     int ret = -1;\r
757     int num = 0;\r
758     struct rga_reg *reg;\r
759     struct rga_req req2;\r
760 \r
761     uint32_t saw, sah, daw, dah;\r
762 \r
763     saw = req->src.act_w;\r
764     sah = req->src.act_h;\r
765     daw = req->dst.act_w;\r
766     dah = req->dst.act_h;\r
767      \r
768     do\r
769     {\r
770         if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah)))\r
771         {\r
772             /* generate 2 cmd for pre scale */            \r
773 \r
774             ret = rga_check_param(req);\r
775                 if(ret == -EINVAL) {\r
776                 printk("req 0 argument is inval\n");\r
777                 break;\r
778                 }\r
779 \r
780             ret = RGA_gen_two_pro(req, &req2);\r
781             if(ret == -EINVAL) {\r
782                 break;\r
783             }\r
784 \r
785             ret = rga_check_param(req);\r
786                 if(ret == -EINVAL) {\r
787                 printk("req 1 argument is inval\n");\r
788                 break;\r
789                 }\r
790 \r
791             ret = rga_check_param(&req2);\r
792                 if(ret == -EINVAL) {\r
793                 printk("req 2 argument is inval\n");\r
794                 break;\r
795                 }\r
796 \r
797             reg = rga_reg_init_2(session, req, &req2);\r
798             if(reg == NULL) {\r
799                 break;\r
800             }\r
801             num = 2;\r
802             \r
803         }\r
804         else\r
805         {\r
806             /* check value if legal */\r
807             ret = rga_check_param(req);\r
808                 if(ret == -EINVAL) {\r
809                 printk("req argument is inval\n");\r
810                 break;\r
811                 }\r
812 \r
813             if(req->render_mode == bitblt_mode)\r
814             {\r
815                 rga_mem_addr_sel(req);\r
816             }\r
817 \r
818             reg = rga_reg_init(session, req);\r
819             if(reg == NULL) {\r
820                 break;\r
821             }\r
822             num = 1;\r
823         }\r
824 \r
825         mutex_lock(&rga_service.lock);\r
826         atomic_add(num, &rga_service.total_running);\r
827         rga_try_set_reg();\r
828         mutex_unlock(&rga_service.lock);\r
829 \r
830         return 0;\r
831     }\r
832     while(0);\r
833 \r
834     return -EFAULT;\r
835 }\r
836 \r
837 static int rga_blit_async(rga_session *session, struct rga_req *req)\r
838 {\r
839         int ret = -1;\r
840 \r
841     #if RGA_TEST\r
842     printk("*** rga_blit_async proc ***\n");\r
843     print_info(req);\r
844     #endif\r
845 \r
846     ret = rga_blit(session, req);\r
847 \r
848     return ret;\r
849 }\r
850 \r
851 static int rga_blit_sync(rga_session *session, struct rga_req *req)\r
852 {\r
853     int ret = -1;\r
854     int ret_timeout = 0;\r
855 \r
856     #if RGA_TEST\r
857     printk("*** rga_blit_sync proc ***\n");\r
858     print_info(req);\r
859     #endif\r
860 \r
861     #if RGA_TEST_TIME\r
862     rga_start = ktime_get();\r
863     #endif\r
864 \r
865     ret = rga_blit(session, req);\r
866 \r
867     ret_timeout = wait_event_interruptible_timeout(session->wait, atomic_read(&session->done), RGA_TIMEOUT_DELAY);\r
868 \r
869     if (unlikely(ret_timeout< 0))\r
870     {\r
871                 pr_err("sync pid %d wait task ret %d\n", session->pid, ret_timeout);\r
872         mutex_lock(&rga_service.lock);\r
873         rga_del_running_list();\r
874         mutex_unlock(&rga_service.lock);\r
875         ret = -ETIMEDOUT;\r
876         }\r
877     else if (0 == ret_timeout)\r
878     {\r
879                 pr_err("sync pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));\r
880         mutex_lock(&rga_service.lock);\r
881         rga_del_running_list_timeout();\r
882         rga_try_set_reg();\r
883         mutex_unlock(&rga_service.lock);\r
884                 ret = -ETIMEDOUT;\r
885         }\r
886 \r
887     #if RGA_TEST_TIME\r
888     rga_end = ktime_get();\r
889     rga_end = ktime_sub(rga_end, rga_start);\r
890     printk("sync one cmd end time %d\n", (int)ktime_to_us(rga_end));\r
891     #endif\r
892 \r
893     return ret;\r
894 }\r
895 \r
896 \r
897 static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)\r
898 {\r
899     struct rga_req *req;\r
900         int ret = 0;\r
901     rga_session *session = (rga_session *)file->private_data;\r
902 \r
903         if (NULL == session)\r
904     {\r
905         printk("%s [%d] rga thread session is null\n",__FUNCTION__,__LINE__);\r
906                 return -EINVAL;\r
907         }\r
908 \r
909     req = kzalloc(sizeof(struct rga_req), GFP_KERNEL);\r
910     if(req == NULL)\r
911     {\r
912         printk("%s [%d] get rga_req mem failed\n",__FUNCTION__,__LINE__);\r
913         return -EINVAL;\r
914     }\r
915 \r
916         mutex_lock(&rga_service.mutex);\r
917 \r
918         switch (cmd)\r
919         {\r
920                 case RGA_BLIT_SYNC:\r
921                 if (unlikely(copy_from_user(req, (struct rga_req*)arg, sizeof(struct rga_req))))\r
922             {\r
923                         ERR("copy_from_user failed\n");\r
924                         ret = -EFAULT;\r
925                 break;\r
926                 }\r
927             ret = rga_blit_sync(session, req);\r
928             break;\r
929                 case RGA_BLIT_ASYNC:\r
930                 if (unlikely(copy_from_user(req, (struct rga_req*)arg, sizeof(struct rga_req))))\r
931             {\r
932                         ERR("copy_from_user failed\n");\r
933                         ret = -EFAULT;\r
934                 break;\r
935                 }\r
936 \r
937             if((atomic_read(&rga_service.total_running) > 16))\r
938             {\r
939                             ret = rga_blit_sync(session, req);\r
940             }\r
941             else\r
942             {\r
943                 ret = rga_blit_async(session, req);\r
944             }\r
945                         break;\r
946                 case RGA_FLUSH:\r
947                         ret = rga_flush(session, arg);\r
948                         break;\r
949         case RGA_GET_RESULT:\r
950             ret = rga_get_result(session, arg);\r
951             break;\r
952         case RGA_GET_VERSION:\r
953             ret = copy_to_user((void *)arg, RGA_VERSION, sizeof(RGA_VERSION));\r
954             //ret = 0;\r
955             break;\r
956                 default:\r
957                         ERR("unknown ioctl cmd!\n");\r
958                         ret = -EINVAL;\r
959                         break;\r
960         }\r
961 \r
962         mutex_unlock(&rga_service.mutex);\r
963 \r
964         kfree(req);\r
965 \r
966         return ret;\r
967 }\r
968 \r
969 static int rga_open(struct inode *inode, struct file *file)\r
970 {\r
971     rga_session *session = kzalloc(sizeof(rga_session), GFP_KERNEL);\r
972         if (NULL == session) {\r
973                 pr_err("unable to allocate memory for rga_session.");\r
974                 return -ENOMEM;\r
975         }\r
976 \r
977         session->pid = current->pid;\r
978     //printk(KERN_DEBUG  "+");\r
979 \r
980         INIT_LIST_HEAD(&session->waiting);\r
981         INIT_LIST_HEAD(&session->running);\r
982         INIT_LIST_HEAD(&session->list_session);\r
983         init_waitqueue_head(&session->wait);\r
984         mutex_lock(&rga_service.lock);\r
985         list_add_tail(&session->list_session, &rga_service.session);\r
986         mutex_unlock(&rga_service.lock);\r
987         atomic_set(&session->task_running, 0);\r
988     atomic_set(&session->num_done, 0);\r
989 \r
990         file->private_data = (void *)session;\r
991 \r
992     //DBG("*** rga dev opened by pid %d *** \n", session->pid);\r
993         return nonseekable_open(inode, file);\r
994 \r
995 }\r
996 \r
997 static int rga_release(struct inode *inode, struct file *file)\r
998 {\r
999     int task_running;\r
1000         rga_session *session = (rga_session *)file->private_data;\r
1001         if (NULL == session)\r
1002                 return -EINVAL;\r
1003     //printk(KERN_DEBUG  "-");\r
1004         task_running = atomic_read(&session->task_running);\r
1005 \r
1006     if (task_running)\r
1007     {\r
1008                 pr_err("rga_service session %d still has %d task running when closing\n", session->pid, task_running);\r
1009                 msleep(100);\r
1010         /*ͬ²½*/\r
1011         }\r
1012 \r
1013         wake_up_interruptible_sync(&session->wait);\r
1014         mutex_lock(&rga_service.lock);\r
1015         list_del(&session->list_session);\r
1016         rga_service_session_clear(session);\r
1017         kfree(session);\r
1018         mutex_unlock(&rga_service.lock);\r
1019 \r
1020     //DBG("*** rga dev close ***\n");\r
1021         return 0;\r
1022 }\r
1023 \r
1024 static irqreturn_t rga_irq_thread(int irq, void *dev_id)\r
1025 {\r
1026         mutex_lock(&rga_service.lock);\r
1027         if (rga_service.enable) {\r
1028                 rga_del_running_list();\r
1029                 rga_try_set_reg();\r
1030         }\r
1031         mutex_unlock(&rga_service.lock);\r
1032 \r
1033         return IRQ_HANDLED;\r
1034 }\r
1035 \r
1036 static irqreturn_t rga_irq(int irq,  void *dev_id)\r
1037 {\r
1038         /*clear INT */\r
1039         rga_write(rga_read(RGA_INT) | (0x1<<6) | (0x1<<7) | (0x1<<4), RGA_INT);\r
1040 \r
1041         return IRQ_WAKE_THREAD;\r
1042 }\r
1043 \r
1044 struct file_operations rga_fops = {\r
1045         .owner          = THIS_MODULE,\r
1046         .open           = rga_open,\r
1047         .release        = rga_release,\r
1048         .unlocked_ioctl         = rga_ioctl,\r
1049 };\r
1050 \r
1051 static struct miscdevice rga_dev ={\r
1052     .minor = RGA_MAJOR,\r
1053     .name  = "rga",\r
1054     .fops  = &rga_fops,\r
1055 };\r
1056 \r
1057 static int __devinit rga_drv_probe(struct platform_device *pdev)\r
1058 {\r
1059         struct rga_drvdata *data;\r
1060         int ret = 0;\r
1061 \r
1062         INIT_LIST_HEAD(&rga_service.waiting);\r
1063         INIT_LIST_HEAD(&rga_service.running);\r
1064         INIT_LIST_HEAD(&rga_service.done);\r
1065         INIT_LIST_HEAD(&rga_service.session);\r
1066         mutex_init(&rga_service.lock);\r
1067         mutex_init(&rga_service.mutex);\r
1068         atomic_set(&rga_service.total_running, 0);\r
1069         atomic_set(&rga_service.src_format_swt, 0);\r
1070         rga_service.last_prc_src_format = 1; /* default is yuv first*/\r
1071         rga_service.enable = false;\r
1072 \r
1073         data = kzalloc(sizeof(struct rga_drvdata), GFP_KERNEL);\r
1074         if(NULL == data)\r
1075         {\r
1076                 ERR("failed to allocate driver data.\n");\r
1077                 return -ENOMEM;\r
1078         }\r
1079 \r
1080         INIT_DELAYED_WORK(&data->power_off_work, rga_power_off_work);\r
1081         wake_lock_init(&data->wake_lock, WAKE_LOCK_SUSPEND, "rga");\r
1082 \r
1083         data->pd_rga = clk_get(NULL, "pd_rga");\r
1084         data->aclk_rga = clk_get(NULL, "aclk_rga");\r
1085         data->hclk_rga = clk_get(NULL, "hclk_rga");\r
1086 \r
1087         /* map the memory */\r
1088         if (!request_mem_region(RK30_RGA_PHYS, RK30_RGA_SIZE, "rga_io"))\r
1089         {\r
1090                 pr_info("failed to reserve rga HW regs\n");\r
1091                 return -EBUSY;\r
1092         }\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 #if 1\r
1243 extern struct fb_info * rk_get_fb(int fb_id);\r
1244 EXPORT_SYMBOL(rk_get_fb);\r
1245 \r
1246 extern void rk_direct_fb_show(struct fb_info * fbi);\r
1247 EXPORT_SYMBOL(rk_direct_fb_show);\r
1248 \r
1249 #endif\r
1250 \r
1251 unsigned int src_buf[320*240];\r
1252 unsigned int dst_buf[1024*768];\r
1253 \r
1254 void rga_test_0(void)\r
1255 {\r
1256     struct rga_req req;\r
1257     rga_session session;\r
1258     unsigned int *src, *dst;\r
1259     uint32_t i, j;\r
1260     uint8_t *p;\r
1261     uint8_t t;\r
1262 \r
1263     struct fb_info *fb;\r
1264 \r
1265     session.pid = current->pid;\r
1266         INIT_LIST_HEAD(&session.waiting);\r
1267         INIT_LIST_HEAD(&session.running);\r
1268         INIT_LIST_HEAD(&session.list_session);\r
1269         init_waitqueue_head(&session.wait);\r
1270         /* no need to protect */\r
1271         list_add_tail(&session.list_session, &rga_service.session);\r
1272         atomic_set(&session.task_running, 0);\r
1273     atomic_set(&session.num_done, 0);\r
1274         //file->private_data = (void *)session;\r
1275 \r
1276     fb = rk_get_fb(0);\r
1277     \r
1278     memset(&req, 0, sizeof(struct rga_req));\r
1279     src = src_buf;\r
1280     dst = dst_buf;\r
1281 \r
1282     memset(src_buf, 0x80, 320*240*4);\r
1283 \r
1284     dmac_flush_range(&src_buf[0], &src_buf[320*240]);\r
1285     outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1286 \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)virt_to_phys(src);\r
1303     req.src.v_addr = (uint32_t)virt_to_phys(src);\r
1304     req.src.format = 0;\r
1305 \r
1306     req.dst.act_w = 320;\r
1307     req.dst.act_h = 240;\r
1308 \r
1309     req.dst.vir_w = 1024;\r
1310     req.dst.vir_h = 768;\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 = 1023;\r
1319     req.clip.ymin = 0;\r
1320     req.clip.ymax = 767;\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 = 1;\r
1329     //req.alpha_rop_mode = 0x19;\r
1330     req.PD_mode = 3;\r
1331 \r
1332     req.sina = 0;\r
1333     req.cosa = 65536;\r
1334 \r
1335     req.mmu_info.mmu_flag = 0x21;\r
1336     req.mmu_info.mmu_en = 1;\r
1337 \r
1338     rga_blit_sync(&session, &req);\r
1339 \r
1340     dmac_inv_range(&dst_buf[0], &dst_buf[320*240]);\r
1341     outer_inv_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[320*240]));\r
1342 \r
1343     for(j=0; j<17; j++)\r
1344     {\r
1345         for(i=0; i<8; i++)\r
1346         {\r
1347             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1348         }\r
1349         printk("\n");\r
1350 \r
1351         for(i=8; i<16; i++)\r
1352         {\r
1353             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1354         }\r
1355         printk("\n");\r
1356     }\r
1357 \r
1358     p = (uint8_t *)src_buf;\r
1359     p = p + 16 * 4;\r
1360 \r
1361     for(i=0; i<16; i++)\r
1362         src_buf[i] = 0;\r
1363 \r
1364     for(j=0; j<16; j++)\r
1365     {\r
1366         for(i=0; i<16; i++)\r
1367         {\r
1368             t = j*16 + i;\r
1369             src_buf[(j+1)*16 + i] = (t<<24)|(t<<16)|(t<<8)|t;\r
1370         }\r
1371     }\r
1372 \r
1373     dmac_flush_range(&src_buf[0], &src_buf[320*240]);\r
1374     outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1375 \r
1376     dmac_inv_range(&src_buf[0], &src_buf[320*240]);\r
1377     outer_inv_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1378 \r
1379     printk("SRC DATA \n");\r
1380     for(j=0; j<17; j++)\r
1381     {\r
1382         for(i=0; i<8; i++)\r
1383         {\r
1384             printk("%.8x, ", src_buf[j*16 + i]);            \r
1385         }\r
1386         printk("\n");\r
1387 \r
1388         for(i=8; i<16; i++)\r
1389         {\r
1390             printk("%.8x, ", src_buf[j*16 + i]);            \r
1391         }\r
1392         printk("\n");\r
1393     }    \r
1394 \r
1395     req.src.act_w = 320;\r
1396     req.src.act_h = 240;\r
1397 \r
1398     req.src.vir_w = 320;\r
1399     req.src.vir_h = 240;\r
1400     req.src.yrgb_addr = (uint32_t)src;\r
1401     req.src.uv_addr = (uint32_t)virt_to_phys(src);\r
1402     req.src.v_addr = (uint32_t)virt_to_phys(src);\r
1403     req.src.format = 0;\r
1404 \r
1405     req.dst.act_w = 320;\r
1406     req.dst.act_h = 240;\r
1407 \r
1408     req.dst.vir_w = 1024;\r
1409     req.dst.vir_h = 768;\r
1410     req.dst.x_offset = 0;\r
1411     req.dst.y_offset = 0;\r
1412     req.dst.yrgb_addr = (uint32_t)(dst);\r
1413 \r
1414     //req.dst.format = RK_FORMAT_RGB_565;\r
1415 \r
1416     req.clip.xmin = 0;\r
1417     req.clip.xmax = 1023;\r
1418     req.clip.ymin = 0;\r
1419     req.clip.ymax = 767;\r
1420 \r
1421     //req.render_mode = color_fill_mode;\r
1422     //req.fg_color = 0x80ffffff;\r
1423 \r
1424     //req.rotate_mode = 1;\r
1425     //req.scale_mode = 2;\r
1426 \r
1427     req.alpha_rop_flag = 0x19;\r
1428     req.alpha_rop_mode = 0x1;\r
1429     req.PD_mode = 3;\r
1430 \r
1431     req.sina = 0;\r
1432     req.cosa = 65536;\r
1433 \r
1434     req.mmu_info.mmu_flag = 0x21;\r
1435     req.mmu_info.mmu_en = 1;\r
1436     \r
1437     rga_blit_sync(&session, &req);\r
1438 \r
1439     dmac_inv_range(&dst_buf[0], &dst_buf[320*240]);\r
1440     outer_inv_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[320*240]));\r
1441 \r
1442     for(j=0; j<17; j++)\r
1443     {\r
1444         for(i=0; i<8; i++)\r
1445         {\r
1446             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1447         }\r
1448         printk("\n");\r
1449         for(i=8; i<16; i++)\r
1450         {\r
1451             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1452         }\r
1453         printk("\n");\r
1454     }\r
1455 \r
1456     memset(src_buf, 0x80, 320*240*4);\r
1457 \r
1458     dmac_flush_range(&src_buf[0], &src_buf[320*240]);\r
1459     outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1460 \r
1461    \r
1462     #if 0\r
1463     memset(src_buf, 0x80, 800*480*4);\r
1464     memset(dst_buf, 0xcc, 800*480*4);\r
1465 \r
1466     dmac_flush_range(&dst_buf[0], &dst_buf[800*480]);\r
1467     outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480]));\r
1468     #endif\r
1469 \r
1470     req.src.act_w = 320;\r
1471     req.src.act_h = 240;\r
1472 \r
1473     req.src.vir_w = 320;\r
1474     req.src.vir_h = 240;\r
1475     req.src.yrgb_addr = (uint32_t)(src);\r
1476     req.src.uv_addr = (uint32_t)virt_to_phys(src);\r
1477     req.src.v_addr = (uint32_t)virt_to_phys(src);\r
1478     req.src.format = 0;\r
1479 \r
1480     req.dst.act_w = 320;\r
1481     req.dst.act_h = 240;\r
1482 \r
1483     req.dst.vir_w = 1024;\r
1484     req.dst.vir_h = 768;\r
1485     req.dst.x_offset = 0;\r
1486     req.dst.y_offset = 0;\r
1487     req.dst.yrgb_addr = (uint32_t)(dst);\r
1488 \r
1489     //req.dst.format = RK_FORMAT_RGB_565;\r
1490 \r
1491     req.clip.xmin = 0;\r
1492     req.clip.xmax = 1023;\r
1493     req.clip.ymin = 0;\r
1494     req.clip.ymax = 767;\r
1495 \r
1496     //req.render_mode = color_fill_mode;\r
1497     //req.fg_color = 0x80ffffff;\r
1498 \r
1499     //req.rotate_mode = 1;\r
1500     //req.scale_mode = 2;\r
1501 \r
1502     req.alpha_rop_flag = 0;\r
1503     req.alpha_rop_mode = 0x0;\r
1504 \r
1505     req.sina = 0;\r
1506     req.cosa = 65536;\r
1507 \r
1508     req.mmu_info.mmu_flag = 0x21;\r
1509     req.mmu_info.mmu_en = 1;\r
1510 \r
1511     rga_blit_sync(&session, &req);\r
1512 \r
1513     dmac_inv_range(&dst_buf[0], &dst_buf[320*240]);\r
1514     outer_inv_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[320*240]));\r
1515 \r
1516     for(j=0; j<17; j++)\r
1517     {\r
1518         for(i=0; i<8; i++)\r
1519         {\r
1520             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1521         }\r
1522         printk("\n");\r
1523 \r
1524         for(i=8; i<16; i++)\r
1525         {\r
1526             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1527         }\r
1528         printk("\n");\r
1529     }\r
1530 \r
1531     p = (uint8_t *)src_buf;\r
1532     p = p + 16 * 4;\r
1533 \r
1534     for(i=0; i<16; i++)\r
1535         src_buf[i] = 0;\r
1536 \r
1537     for(j=0; j<16; j++)\r
1538     {\r
1539         for(i=0; i<16; i++)\r
1540         {\r
1541             t = j*16 + i;\r
1542             src_buf[(j+1)*16 + i] = (t<<24)|(t<<16)|(t<<8)|t;\r
1543         }\r
1544     }\r
1545 \r
1546     dmac_inv_range(&src_buf[0], &src_buf[320*240]);\r
1547     outer_inv_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1548     printk("SRC DATA \n");\r
1549     for(j=0; j<17; j++)\r
1550     {\r
1551         for(i=0; i<8; i++)\r
1552         {\r
1553             printk("%.8x, ", src_buf[j*16 + i]);            \r
1554         }\r
1555         printk("\n");\r
1556 \r
1557         for(i=8; i<16; i++)\r
1558         {\r
1559             printk("%.8x, ", src_buf[j*16 + i]);            \r
1560         }\r
1561         printk("\n");\r
1562     }\r
1563 \r
1564     dmac_flush_range(&src_buf[0], &src_buf[320*240]);\r
1565     outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[320*240]));\r
1566 \r
1567     req.src.act_w = 320;\r
1568     req.src.act_h = 240;\r
1569 \r
1570     req.src.vir_w = 320;\r
1571     req.src.vir_h = 240;\r
1572     req.src.yrgb_addr = (uint32_t)(src);\r
1573     req.src.uv_addr = (uint32_t)virt_to_phys(src);\r
1574     req.src.v_addr = (uint32_t)virt_to_phys(src);\r
1575     req.src.format = 0;\r
1576 \r
1577     req.dst.act_w = 320;\r
1578     req.dst.act_h = 240;\r
1579 \r
1580     req.dst.vir_w = 1024;\r
1581     req.dst.vir_h = 768;\r
1582     req.dst.x_offset = 0;\r
1583     req.dst.y_offset = 0;\r
1584     req.dst.yrgb_addr = (uint32_t)(dst);\r
1585 \r
1586     //req.dst.format = RK_FORMAT_RGB_565;\r
1587 \r
1588     req.clip.xmin = 0;\r
1589     req.clip.xmax = 1023;\r
1590     req.clip.ymin = 0;\r
1591     req.clip.ymax = 767;\r
1592 \r
1593     //req.render_mode = color_fill_mode;\r
1594     //req.fg_color = 0x80ffffff;\r
1595 \r
1596     //req.rotate_mode = 1;\r
1597     //req.scale_mode = 2;\r
1598 \r
1599     req.alpha_rop_flag = 0x19;\r
1600     req.alpha_rop_mode = 0x1;\r
1601     req.PD_mode = 3;\r
1602 \r
1603     req.sina = 0;\r
1604     req.cosa = 65536;\r
1605 \r
1606     req.mmu_info.mmu_flag = 0x21;\r
1607     req.mmu_info.mmu_en = 1;\r
1608     \r
1609     rga_blit_sync(&session, &req);\r
1610 \r
1611     dmac_inv_range(&dst_buf[0], &dst_buf[320*240]);\r
1612     outer_inv_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[320*240]));\r
1613 \r
1614     for(j=0; j<17; j++)\r
1615     {\r
1616         for(i=0; i<8; i++)\r
1617         {\r
1618             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1619         }\r
1620         printk("\n");\r
1621         for(i=8; i<16; i++)\r
1622         {\r
1623             printk("%.8x, ", dst_buf[j*16 + i]);            \r
1624         }\r
1625         printk("\n");\r
1626     }\r
1627 \r
1628     #if 1\r
1629     fb->var.bits_per_pixel = 32;\r
1630     \r
1631     fb->var.xres = 1024;\r
1632     fb->var.yres = 768;\r
1633 \r
1634     fb->var.red.length = 8;\r
1635     fb->var.red.offset = 0;\r
1636     fb->var.red.msb_right = 0;\r
1637 \r
1638     fb->var.green.length = 8;\r
1639     fb->var.green.offset = 8;\r
1640     fb->var.green.msb_right = 0;\r
1641 \r
1642     fb->var.blue.length = 8;\r
1643 \r
1644     fb->var.blue.offset = 16;\r
1645     fb->var.blue.msb_right = 0;\r
1646 \r
1647     fb->var.transp.length = 8;\r
1648     fb->var.transp.offset = 24;\r
1649     fb->var.transp.msb_right = 0;\r
1650 \r
1651     fb->var.nonstd &= (~0xff);\r
1652     fb->var.nonstd |= 1;\r
1653 \r
1654     fb->fix.smem_start = virt_to_phys(dst);\r
1655 \r
1656     rk_direct_fb_show(fb);\r
1657     #endif\r
1658 \r
1659 }\r
1660 \r
1661 #endif\r
1662 module_init(rga_init);\r
1663 module_exit(rga_exit);\r
1664 \r
1665 /* Module information */\r
1666 MODULE_AUTHOR("zsq@rock-chips.com");\r
1667 MODULE_DESCRIPTION("Driver for rga device");\r
1668 MODULE_LICENSE("GPL");\r