g2d.c 19 KB

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