g2d.c 16 KB

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