1 /*
2 * g2d_rcq/g2d_driver/g2d.c
3 *
4 * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6 *
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18 #include <hal_mem.h>
19 #include <hal_cache.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <hal_interrupt.h>
23 #include <init.h>
24 #include <hal_clk.h>
25 #include <hal_reset.h>
26 #include <hal_timer.h>
27 /* #include <melis/standby/standby.h> */
28
29 #include "g2d_driver_i.h"
30 #include "g2d_top.h"
31 #include "g2d_mixer.h"
32 #include "g2d_rotate.h"
33
34 #define SUNXI_GIC_START 32
35
36 #if defined(CONFIG_ARCH_SUN8IW19)
37 #define SUNXI_IRQ_G2D (SUNXI_GIC_START + 21)
38 #define SUNXI_G2D_START 0x01480000
39 #define SUNXI_G2D_RESET_ID 0
40 #define SUNXI_G2D_CLK_ID HAL_CLK_PERIPH_G2D
41 #define SUNXI_G2D_CLK_BUS_ID (hal_clk_id_t)(-1)
42 #define SUNXI_G2D_CLK_MBUS_ID (hal_clk_id_t)(-1)
43 #define SUNXI_G2D_CLK_PARENT HAL_CLK_PLL_PERI1
44
45 #elif defined(CONFIG_SOC_SUN20IW1)
46 #define SUNXI_IRQ_G2D 105
47 #define SUNXI_G2D_START 0x05410000
48 #define RESET_IOMMU
49 #define G2D_IOMMU_MASTER_ID 3
50 #define IOMMU_RESET_REG 0x02010010
51 #define IOMMU_BGR_REG 0x020017bc
52 #endif
53
54 #ifndef SUNXI_G2D_CLK_ID
55 #define SUNXI_G2D_CLK_ID CLK_G2D
56 #endif
57 #ifndef SUNXI_G2D_RESET_ID
58 #define SUNXI_G2D_RESET_ID RST_BUS_G2D
59 #endif
60 #ifndef SUNXI_G2D_CLK_BUS_ID
61 #define SUNXI_G2D_CLK_BUS_ID CLK_BUS_G2D
62 #endif
63 #ifndef SUNXI_G2D_CLK_MBUS_ID
64 #define SUNXI_G2D_CLK_MBUS_ID CLK_MBUS_G2D
65 #endif
66 #ifndef SUNXI_G2D_CLK_PARENT
67 #define SUNXI_G2D_CLK_PARENT CLK_PLL_PERIPH0_2X
68 #endif
69
70 enum g2d_scan_order scan_order;
71 hal_sem_t global_lock;
72 u32 g_time_info;
73 u32 g_func_runtime;
74 __g2d_drv_t g2d_ext_hd;
75 __g2d_info_t para;
76
77 __u32 dbg_info;
78
g2d_malloc(__u32 bytes_num,__u32 * phy_addr)79 void *g2d_malloc(__u32 bytes_num, __u32 *phy_addr)
80 {
81
82 char* vir_addr;
83
84 if (bytes_num != 0)
85 {
86 vir_addr = hal_malloc_align(bytes_num, CACHELINE_LEN);
87 if(vir_addr!=NULL)
88 {
89 *phy_addr = __va_to_pa((unsigned long)vir_addr);
90 memset((void *)vir_addr, 0, bytes_num);
91 hal_dcache_clean((unsigned long)vir_addr, bytes_num);
92 return vir_addr;
93 }
94 G2D_ERR_MSG("hal_malloc fail!\n");
95 return NULL;
96 }
97 G2D_ERR_MSG("size is zero\n");
98
99 return NULL;
100 }
101
g2d_free(void * virt_addr,void * phy_addr,unsigned int size)102 void g2d_free(void *virt_addr, void *phy_addr, unsigned int size)
103 {
104
105 if (virt_addr == NULL)
106 return;
107 hal_free_align(virt_addr);
108 }
109
g2d_mutex_lock(hal_sem_t sem)110 int g2d_mutex_lock(hal_sem_t sem)
111 {
112 return hal_sem_wait(sem);
113 }
114
g2d_mutex_unlock(hal_sem_t sem)115 int g2d_mutex_unlock(hal_sem_t sem)
116 {
117 return hal_sem_post(sem);
118 }
119
g2d_byte_cal(__u32 format,__u32 * ycnt,__u32 * ucnt,__u32 * vcnt)120 __s32 g2d_byte_cal(__u32 format, __u32 *ycnt, __u32 *ucnt, __u32 *vcnt)
121 {
122 *ycnt = 0;
123 *ucnt = 0;
124 *vcnt = 0;
125 if (format <= G2D_FORMAT_BGRX8888)
126 *ycnt = 4;
127
128 else if (format <= G2D_FORMAT_BGR888)
129 *ycnt = 3;
130
131 else if (format <= G2D_FORMAT_BGRA5551)
132 *ycnt = 2;
133
134 else if (format <= G2D_FORMAT_BGRA1010102)
135 *ycnt = 4;
136
137 else if (format <= 0x23)
138 {
139 *ycnt = 2;
140 }
141
142 else if (format <= 0x25)
143 {
144 *ycnt = 1;
145 *ucnt = 2;
146 }
147
148 else if (format == 0x26)
149 {
150 *ycnt = 1;
151 *ucnt = 1;
152 *vcnt = 1;
153 }
154
155 else if (format <= 0x29)
156 {
157 *ycnt = 1;
158 *ucnt = 2;
159 }
160
161 else if (format == 0x2a)
162 {
163 *ycnt = 1;
164 *ucnt = 1;
165 *vcnt = 1;
166 }
167
168 else if (format <= 0x2d)
169 {
170 *ycnt = 1;
171 *ucnt = 2;
172 }
173
174 else if (format == 0x2e)
175 {
176 *ycnt = 1;
177 *ucnt = 1;
178 *vcnt = 1;
179 }
180
181 else if (format == 0x30)
182 *ycnt = 1;
183
184 else if (format <= 0x36)
185 {
186 *ycnt = 2;
187 *ucnt = 4;
188 }
189
190 else if (format <= 0x39)
191 *ycnt = 6;
192 return 0;
193 }
194
195
196 /**
197 */
cal_align(__u32 width,__u32 align)198 __u32 cal_align(__u32 width, __u32 align)
199 {
200 switch (align)
201 {
202 case 0:
203 return width;
204 case 4:
205 return (width + 3) >> 2 << 2;
206 case 8:
207 return (width + 7) >> 3 << 3;
208 case 16:
209 return (width + 15) >> 4 << 4;
210 case 32:
211 return (width + 31) >> 5 << 5;
212 case 64:
213 return (width + 63) >> 6 << 6;
214 case 128:
215 return (width + 127) >> 7 << 7;
216 default:
217 return (width + 31) >> 5 << 5;
218 }
219 }
220
221
g2d_image_check(g2d_image_enh * p_image)222 __s32 g2d_image_check(g2d_image_enh *p_image)
223 {
224 __s32 ret = -EINVAL;
225
226 if (!p_image)
227 {
228 G2D_ERR_MSG("NUll pointer!\n");
229 goto OUT;
230 }
231
232 if (((p_image->clip_rect.x < 0) &&
233 ((-p_image->clip_rect.x) > p_image->clip_rect.w)) ||
234 ((p_image->clip_rect.y < 0) &&
235 ((-p_image->clip_rect.y) > p_image->clip_rect.h)) ||
236 ((p_image->clip_rect.x > 0) &&
237 (p_image->clip_rect.x > p_image->width - 1)) ||
238 ((p_image->clip_rect.y > 0) &&
239 (p_image->clip_rect.y > p_image->height - 1)))
240 {
241 G2D_ERR_MSG("Invalid imager parameter setting\n");
242 goto OUT;
243 }
244
245 if (((p_image->clip_rect.x < 0) &&
246 ((-p_image->clip_rect.x) <
247 p_image->clip_rect.w)))
248 {
249 p_image->clip_rect.w =
250 p_image->clip_rect.w +
251 p_image->clip_rect.x;
252 p_image->clip_rect.x = 0;
253 } else if ((p_image->clip_rect.x +
254 p_image->clip_rect.w)
255 > p_image->width)
256 {
257 p_image->clip_rect.w =
258 p_image->width -
259 p_image->clip_rect.x;
260 }
261 if (((p_image->clip_rect.y < 0) &&
262 ((-p_image->clip_rect.y) <
263 p_image->clip_rect.h)))
264 {
265 p_image->clip_rect.h =
266 p_image->clip_rect.h +
267 p_image->clip_rect.y;
268 p_image->clip_rect.y = 0;
269 } else if ((p_image->clip_rect.y +
270 p_image->clip_rect.h)
271 > p_image->height)
272 {
273 p_image->clip_rect.h =
274 p_image->height -
275 p_image->clip_rect.y;
276 }
277
278 p_image->bpremul = 0;
279 p_image->bbuff = 1;
280 p_image->gamut = G2D_BT709;
281 ret = 0;
282 OUT:
283 return ret;
284
285 }
286
g2d_blit_h(g2d_blt_h * para)287 int g2d_blit_h(g2d_blt_h *para)
288 {
289 int ret = -1;
290
291 ret = g2d_rotate_set_para(¶->src_image_h,
292 ¶->dst_image_h,
293 para->flag_h);
294
295 return ret;
296 }
297
298 #ifdef RESET_IOMMU
299 /**
300 * g2d could cause iommu stop, when iommu stop, g2d could not work, we should reset iommu.
301 */
reset_iommu(void)302 static void reset_iommu(void)
303 {
304 int tmp;
305 int ret;
306 uint32_t regval;
307 *(volatile uint32_t *)(IOMMU_BGR_REG) = 0x1;
308 regval = (*(volatile uint32_t *)(IOMMU_RESET_REG));
309
310 *(volatile uint32_t *)(IOMMU_RESET_REG) = regval & (~(1 << G2D_IOMMU_MASTER_ID));
311 regval = (*(volatile uint32_t *)(IOMMU_RESET_REG));
312 if (!(regval & ((1 << G2D_IOMMU_MASTER_ID))))
313 {
314 *(volatile uint32_t *)(IOMMU_RESET_REG) = regval | ((1 << G2D_IOMMU_MASTER_ID));
315 }
316 regval = (*(volatile uint32_t *)(IOMMU_RESET_REG));
317
318 *(volatile uint32_t *)(IOMMU_BGR_REG) = 0;
319 return;
320 }
321 #else
reset_iommu(void)322 static void reset_iommu(void)
323 {
324 }
325 #endif
326
g2d_wait_cmd_finish(unsigned int timeout)327 int g2d_wait_cmd_finish(unsigned int timeout)
328 {
329 int ret;
330 ret = hal_sem_timedwait(g2d_ext_hd.queue_sem,timeout* 10);
331 if (ret < 0)
332 {
333 reset_iommu();
334 g2d_bsp_reset();
335 G2D_ERR_MSG("G2D irq pending flag timeout\n");
336 g2d_ext_hd.finish_flag = 1;
337 /* wake_up(&g2d_ext_hd.queue); */
338 return -1;
339 }
340 g2d_ext_hd.finish_flag = 0;
341
342 return 0;
343 }
344
g2d_handle_irq(int irq,void * dev_id)345 irqreturn_t g2d_handle_irq(int irq, void *dev_id)
346 {
347 #if G2D_MIXER_RCQ_USED == 1
348 if (g2d_top_rcq_task_irq_query())
349 {
350 /* g2d_top_mixer_reset(); */
351 g2d_ext_hd.finish_flag = 1;
352 hal_sem_post(g2d_ext_hd.queue_sem);
353 return IRQ_HANDLED;
354 }
355 #else
356 if (g2d_mixer_irq_query())
357 {
358 /* g2d_top_mixer_reset(); */
359 g2d_ext_hd.finish_flag = 1;
360 hal_sem_post(g2d_ext_hd.queue_sem);
361 return IRQ_HANDLED;
362 }
363 #endif
364 if (g2d_rot_irq_query())
365 {
366 /* g2d_top_rot_reset(); */
367 g2d_ext_hd.finish_flag = 1;
368 hal_sem_post(g2d_ext_hd.queue_sem);
369 return IRQ_HANDLED;
370 }
371
372 return IRQ_HANDLED;
373 }
374
g2d_clk_init(__g2d_info_t * info)375 int g2d_clk_init(__g2d_info_t *info)
376 {
377 int i;
378 int ret;
379 hal_reset_id_t rst_id;
380 hal_reset_type_t reset_type = HAL_SUNXI_RESET;
381 hal_clk_type_t clk_type = HAL_SUNXI_CCU;
382 hal_clk_id_t clk_id[G2D_CLK_NUM] = {
383 SUNXI_G2D_CLK_ID,/*note SUNXI_G2D_CLK_ID must be here, please see g2d_clock_enable*/
384 SUNXI_G2D_CLK_BUS_ID,
385 SUNXI_G2D_CLK_MBUS_ID,
386 };
387 info->clk_rate = 300000000; /*300Mhz*/
388 info->reset = hal_reset_control_get(reset_type, SUNXI_G2D_RESET_ID);
389 hal_reset_control_deassert(info->reset);
390 info->clk_parent= hal_clock_get(clk_type,SUNXI_G2D_CLK_PARENT);
391 for(i = 0; i < G2D_CLK_NUM; i++)
392 {
393 if (clk_id[i] != (hal_clk_id_t)-1)
394 {
395 info->clk[i] = hal_clock_get(clk_type, clk_id[i]);
396 }
397 }
398 ret = hal_clk_set_parent(info->clk[0], info->clk_parent);
399 if (ret)
400 G2D_ERR_MSG("set clk:%d's parent:%d fail!\n", info->clk, info->clk_parent);
401 return ret;
402 }
403
g2d_clk_exit(__g2d_info_t * info)404 int g2d_clk_exit(__g2d_info_t *info)
405 {
406 int i = 0;
407 for(i = 0; i < G2D_CLK_NUM; i++)
408 {
409 hal_clock_put(info->clk[i]);
410 }
411
412 hal_reset_control_put(info->reset);
413
414 return 0;
415 }
416
g2d_clock_enable(__g2d_info_t * info)417 int g2d_clock_enable(__g2d_info_t *info)
418 {
419 int ret = -1;
420 int i = 0;
421 ret = hal_reset_control_deassert(info->reset);
422 if (ret)
423 {
424 G2D_ERR_MSG("deassert rst fail:%d\n", ret);
425 goto OUT;
426 }
427
428 ret = hal_clock_enable(info->clk_parent);
429 if (ret)
430 {
431 G2D_ERR_MSG("Enable clk parent fail:%d\n", ret);
432 goto OUT;
433 }
434
435 ret = hal_clk_set_rate(info->clk[0], info->clk_rate);
436 if (ret)
437 {
438 G2D_ERR_MSG("Set clk rate fail:%d:%u!\n", info->clk[0], (unsigned int)info->clk_rate);
439 goto OUT;
440 }
441
442 for(i = 0; i < G2D_CLK_NUM; i++)
443 {
444 ret = hal_clock_enable(info->clk[i]);
445 if (ret)
446 {
447 G2D_ERR_MSG("Enable clk %d fail:%d\n", i, ret);
448 goto OUT;
449 }
450 }
451
452 OUT:
453 return ret;
454 }
455
g2d_clock_disable(__g2d_info_t * info)456 static int g2d_clock_disable(__g2d_info_t *info)
457 {
458 int ret = -1;
459 int i;
460 for(i = 0; i < G2D_CLK_NUM; i++)
461 {
462 ret = hal_clock_disable(info->clk[i]);
463 if (ret)
464 {
465 G2D_ERR_MSG("Disable clk %d fail:%d\n", i, ret);
466 goto OUT;
467 }
468 }
469
470 ret = hal_reset_control_assert(info->reset);
471 if (ret)
472 {
473 G2D_ERR_MSG("assert rst fail:%d\n", ret);
474 goto OUT;
475 }
476 OUT:
477 return ret;
478 }
479
drv_g2d_init(__g2d_info_t * info)480 __s32 drv_g2d_init(__g2d_info_t *info)
481 {
482 int ret;
483 memset(&g2d_ext_hd, 0, sizeof(__g2d_drv_t));
484
485 g2d_ext_hd.queue_sem = hal_sem_create(0);
486 if (g2d_ext_hd.queue_sem == NULL)
487 {
488 G2D_ERR_MSG("create g2d_ext_hd.queue_sem failed\n");
489 return -1;
490 }
491
492
493 g2d_top_set_base((__u32)info->io);
494 g2d_rot_set_base((__u32)info->io);
495 g2d_mixer_idr_init();
496 return 0;
497 }
498
499 #ifdef CONFIG_STANDBY
500 /**
501 * @desc This function suspend the g2d
502 * @param null
503 */
g2d_suspend(void)504 int g2d_suspend(void)
505 {
506 g2d_mutex_lock(para.mutex);
507 if (para.opened)
508 {
509 g2d_clock_disable(¶);
510 g2d_bsp_close();
511 }
512 g2d_mutex_unlock(para.mutex);
513
514 return 0;
515 }
516
517 /**
518 * @desc This function resume the g2d
519 * @param null
520 */
g2d_resume(void)521 int g2d_resume(void)
522 {
523 g2d_mutex_lock(para.mutex);
524 if (para.opened)
525 {
526 g2d_clock_enable(¶);
527 g2d_bsp_open();
528 }
529 g2d_mutex_unlock(para.mutex);
530
531 return 0;
532 }
533
g2d_register_pm_dev_notify(void)534 static void g2d_register_pm_dev_notify(void)
535 {
536 register_pm_dev_notify(g2d_suspend, g2d_resume, NULL);
537 }
538 #else
g2d_register_pm_dev_notify(void)539 static void g2d_register_pm_dev_notify(void)
540 {
541 }
542 #endif
543
g2d_probe(void)544 int g2d_probe(void)
545 {
546 int ret = 0;
547 __g2d_info_t *info = NULL;
548
549 info = ¶
550 memset(info, 0, sizeof(__g2d_info_t));
551 info->io = SUNXI_G2D_START;
552
553 if (request_irq(SUNXI_IRQ_G2D, g2d_handle_irq, 0, "g2d", NULL))
554 {
555 G2D_ERR_MSG("g2d request irq error\n");
556 return -1;
557 }
558 enable_irq(SUNXI_IRQ_G2D);
559
560 g2d_clk_init(info);
561 drv_g2d_init(info);
562 info->mutex = hal_sem_create(1);
563 global_lock = hal_sem_create(1);
564 if ((info->mutex == NULL) || (global_lock == NULL))
565 {
566 G2D_ERR_MSG("sysfs_create_file fail!\n");
567 ret = -1;
568 }
569
570 g2d_register_pm_dev_notify();
571
572 G2D_INFO_MSG("g2d probe finished\n");
573 return ret;
574 }
575
g2d_remove(void)576 static int g2d_remove(void)
577 {
578 __g2d_info_t *info = ¶
579
580 g2d_clk_exit(info);
581 g2d_mixer_idr_remove();
582 INFO("Driver unloaded succesfully.\n");
583 return 0;
584 }
585
g2d_ioctl_mutex_lock(void)586 void g2d_ioctl_mutex_lock(void)
587 {
588
589 g2d_mutex_lock(para.mutex);
590
591 }
592
593
g2d_ioctl_mutex_unlock(void)594 void g2d_ioctl_mutex_unlock(void)
595 {
596 g2d_mutex_unlock(para.mutex);
597 }
598
sunxi_g2d_open(void)599 int sunxi_g2d_open(void)
600 {
601 g2d_mutex_lock(para.mutex);
602 g2d_clock_enable(¶);
603 para.user_cnt++;
604 if (para.user_cnt == 1)
605 {
606 para.opened = true;
607 g2d_bsp_open();
608 }
609 g2d_mutex_unlock(para.mutex);
610 return 0;
611
612 }
613
sunxi_g2d_close(void)614 int sunxi_g2d_close(void)
615 {
616 g2d_mutex_lock(para.mutex);
617 para.user_cnt--;
618 if (para.user_cnt == 0)
619 {
620 para.opened = false;
621 g2d_bsp_close();
622 }
623 g2d_clock_disable(¶);
624 g2d_mutex_unlock(para.mutex);
625
626 g2d_mutex_lock(global_lock);
627 scan_order = G2D_SM_TDLR;
628 g2d_mutex_unlock(global_lock);
629
630 return 0;
631
632 }
633
sunxi_g2d_control(int cmd,void * arg)634 int sunxi_g2d_control(int cmd, void *arg)
635 {
636 int ret = -1;
637
638 g2d_ioctl_mutex_lock();
639
640 g2d_ext_hd.finish_flag = 0;
641 switch (cmd)
642 {
643 case G2D_CMD_MIXER_TASK:
644 {
645
646 unsigned long *karg;
647 karg = arg;
648 ret = mixer_task_process(¶, (struct mixer_para *)karg[0], karg[1]);
649 break;
650 }
651 case G2D_CMD_CREATE_TASK:
652 {
653
654 unsigned long *karg;
655 karg = arg;
656 ret = create_mixer_task(¶, (struct mixer_para *)karg[0], karg[1]);
657 break;
658 }
659 case G2D_CMD_TASK_APPLY:
660 {
661
662
663 unsigned long *karg;
664 karg = arg;
665
666
667 struct g2d_mixer_task *p_task = NULL;
668 p_task = g2d_mixer_get_inst((int)karg[0]);
669 ret = p_task->apply(p_task, (struct mixer_para *)karg[1]);
670
671
672
673 break;
674 }
675 case G2D_CMD_TASK_DESTROY:
676 {
677
678 struct g2d_mixer_task *p_task = NULL;
679 p_task = g2d_mixer_get_inst((int)(unsigned long)arg);
680 ret = p_task->destory(p_task);
681 break;
682 }
683 case G2D_CMD_TASK_GET_PARA:
684 {
685
686 unsigned long *karg;
687 karg = arg;
688 struct g2d_mixer_task *p_task = NULL;
689
690 p_task = g2d_mixer_get_inst((int)karg[0]);
691 if(!p_task)
692 {
693 ret = -EFAULT;
694 goto err_noput;
695 }
696
697 karg[1] = (unsigned long)(p_task->p_para);
698 ret = 0;
699 break;
700 }
701 case G2D_CMD_BITBLT_H:
702 {
703 g2d_blt_h blit_para;
704
705
706 memcpy(&blit_para, arg, sizeof(g2d_blt_h));
707 if (blit_para.flag_h & 0xff00)
708 {
709 ret = g2d_blit_h(&blit_para);
710 }
711
712 else {
713 struct mixer_para mixer_blit_para;
714 memset(&mixer_blit_para, 0, sizeof(struct mixer_para));
715 memcpy(&mixer_blit_para.dst_image_h,
716 &blit_para.dst_image_h, sizeof(g2d_image_enh));
717 memcpy(&mixer_blit_para.src_image_h,
718 &blit_para.src_image_h, sizeof(g2d_image_enh));
719 mixer_blit_para.flag_h = blit_para.flag_h;
720 mixer_blit_para.op_flag = OP_BITBLT;
721 ret = mixer_task_process(¶, &mixer_blit_para, 1);
722
723 }
724
725
726 break;
727 }
728
729 case G2D_CMD_LBC_ROT:
730 {
731 g2d_lbc_rot lbc_para;
732 memcpy(&lbc_para, (g2d_lbc_rot *)arg, sizeof(g2d_lbc_rot));
733 ret = g2d_lbc_rot_set_para(&lbc_para);
734 break;
735 }
736
737 case G2D_CMD_BLD_H:{
738
739 g2d_bld bld_para;
740 struct mixer_para mixer_bld_para;
741
742
743
744 memcpy(&bld_para, (g2d_bld *) arg, sizeof(g2d_bld));
745 memset(&mixer_bld_para, 0, sizeof(struct mixer_para));
746 memcpy(&mixer_bld_para.dst_image_h,
747 &bld_para.dst_image, sizeof(g2d_image_enh));
748 memcpy(&mixer_bld_para.src_image_h,
749 &bld_para.src_image[0], sizeof(g2d_image_enh));
750 /* ptn use as src */
751 memcpy(&mixer_bld_para.ptn_image_h,
752 &bld_para.src_image[1], sizeof(g2d_image_enh));
753 memcpy(&mixer_bld_para.ck_para, &bld_para.ck_para,
754 sizeof(g2d_ck));
755 mixer_bld_para.bld_cmd = bld_para.bld_cmd;
756 mixer_bld_para.op_flag = OP_BLEND;
757
758 ret = mixer_task_process(¶, &mixer_bld_para, 1);
759
760 break;
761 }
762 case G2D_CMD_FILLRECT_H:{
763
764 g2d_fillrect_h fill_para;
765 struct mixer_para mixer_fill_para;
766
767
768 memcpy(&fill_para, (g2d_fillrect_h *) arg, sizeof(g2d_fillrect_h));
769 memset(&mixer_fill_para, 0, sizeof(struct mixer_para));
770 memcpy(&mixer_fill_para.dst_image_h,
771 &fill_para.dst_image_h, sizeof(g2d_image_enh));
772 mixer_fill_para.op_flag = OP_FILLRECT;
773
774 ret = mixer_task_process(¶, &mixer_fill_para, 1);
775
776 break;
777 }
778 case G2D_CMD_MASK_H:{
779
780 g2d_maskblt mask_para;
781 struct mixer_para mixer_mask_para;
782
783 memcpy(&mask_para, (g2d_maskblt *) arg, sizeof(g2d_maskblt));
784 memset(&mixer_mask_para, 0, sizeof(struct mixer_para));
785 memcpy(&mixer_mask_para.ptn_image_h,
786 &mask_para.ptn_image_h, sizeof(g2d_image_enh));
787 memcpy(&mixer_mask_para.mask_image_h,
788 &mask_para.mask_image_h, sizeof(g2d_image_enh));
789 memcpy(&mixer_mask_para.dst_image_h,
790 &mask_para.dst_image_h, sizeof(g2d_image_enh));
791 memcpy(&mixer_mask_para.src_image_h,
792 &mask_para.src_image_h, sizeof(g2d_image_enh));
793 mixer_mask_para.back_flag = mask_para.back_flag;
794 mixer_mask_para.fore_flag = mask_para.fore_flag;
795 mixer_mask_para.op_flag = OP_MASK;
796
797 ret = mixer_task_process(¶, &mixer_mask_para, 1);
798
799 break;
800 }
801 case G2D_CMD_INVERTED_ORDER:
802 {
803 if ((enum g2d_scan_order)arg > G2D_SM_DTRL)
804 {
805 G2D_ERR_MSG("scan mode is err.\n");
806 ret = -EINVAL;
807 goto err_noput;
808 }
809
810 g2d_mutex_lock(global_lock);
811 scan_order = (enum g2d_scan_order)arg;
812 g2d_mutex_unlock(global_lock);
813 ret = 0;
814 break;
815 }
816
817 default:
818 goto err_noput;
819 break;
820 }
821
822 err_noput:
823 g2d_ioctl_mutex_unlock();
824
825 return ret;
826 }
827
828