ipptest: add fimc and rotator test applications
[platform/upstream/libdrm.git] / tests / ipptest / fimc.c
1 /*
2  * DRM based fimc test program
3  * Copyright 2012 Samsung Electronics
4  *   Eunchul Kim <chulspro.kim@sasmsung.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdint.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <sys/time.h>
32 #include <sys/mman.h>
33
34 #include "exynos_drm.h"
35 #include "fimctest.h"
36 #include "gem.h"
37 #include "util.h"
38
39 #include "drm_fourcc.h"
40
41 static int exynos_drm_ipp_set_property(int fd,
42                                 struct drm_exynos_ipp_property *property,
43                                 struct drm_exynos_sz *def_sz,
44                                 enum drm_exynos_ipp_cmd cmd,
45                                 enum drm_exynos_degree degree)
46 {
47         struct drm_exynos_pos crop_pos = {0, 0, def_sz->hsize, def_sz->vsize};
48         struct drm_exynos_pos scale_pos = {0, 0, def_sz->hsize, def_sz->vsize};
49         struct drm_exynos_sz src_sz = {def_sz->hsize, def_sz->vsize};
50         struct drm_exynos_sz dst_sz = {def_sz->hsize, def_sz->vsize};
51         int ret = 0;
52
53         memset(property, 0x00, sizeof(struct drm_exynos_ipp_property));
54         property->cmd = cmd;
55
56         switch(cmd) {
57         case IPP_CMD_M2M:
58                 property->config[EXYNOS_DRM_OPS_SRC].ops_id = EXYNOS_DRM_OPS_SRC;
59                 property->config[EXYNOS_DRM_OPS_SRC].flip = EXYNOS_DRM_FLIP_NONE;
60                 property->config[EXYNOS_DRM_OPS_SRC].degree = EXYNOS_DRM_DEGREE_0;
61                 property->config[EXYNOS_DRM_OPS_SRC].fmt = DRM_FORMAT_XRGB8888;
62                 property->config[EXYNOS_DRM_OPS_SRC].pos = crop_pos;
63                 property->config[EXYNOS_DRM_OPS_SRC].sz = src_sz;
64
65                 property->config[EXYNOS_DRM_OPS_DST].ops_id = EXYNOS_DRM_OPS_DST;
66                 property->config[EXYNOS_DRM_OPS_DST].flip = EXYNOS_DRM_FLIP_NONE;
67                 property->config[EXYNOS_DRM_OPS_DST].degree = degree;
68                 property->config[EXYNOS_DRM_OPS_DST].fmt = DRM_FORMAT_XRGB8888;
69                 if (property->config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_90) {
70                         dst_sz.hsize = def_sz->vsize;
71                         dst_sz.vsize = def_sz->hsize;
72
73                         scale_pos.w = def_sz->vsize;
74                         scale_pos.h = def_sz->hsize;
75                 }
76                 property->config[EXYNOS_DRM_OPS_DST].pos = scale_pos;
77                 property->config[EXYNOS_DRM_OPS_DST].sz = dst_sz;
78                 break;
79         case IPP_CMD_WB:
80                 property->config[EXYNOS_DRM_OPS_SRC].ops_id = EXYNOS_DRM_OPS_SRC;
81                 property->config[EXYNOS_DRM_OPS_SRC].flip = EXYNOS_DRM_FLIP_NONE;
82                 property->config[EXYNOS_DRM_OPS_SRC].degree = EXYNOS_DRM_DEGREE_0;
83                 property->config[EXYNOS_DRM_OPS_SRC].fmt = DRM_FORMAT_YUV444;
84                 if (property->config[EXYNOS_DRM_OPS_SRC].degree == EXYNOS_DRM_DEGREE_90) {
85                         src_sz.hsize = def_sz->vsize;
86                         src_sz.vsize = def_sz->hsize;
87
88                         crop_pos.w = def_sz->vsize;
89                         crop_pos.h = def_sz->hsize;
90                 }
91                 property->config[EXYNOS_DRM_OPS_SRC].pos = crop_pos;
92                 property->config[EXYNOS_DRM_OPS_SRC].sz = src_sz;
93
94                 property->config[EXYNOS_DRM_OPS_DST].ops_id = EXYNOS_DRM_OPS_DST;
95                 property->config[EXYNOS_DRM_OPS_DST].flip = EXYNOS_DRM_FLIP_NONE;
96                 property->config[EXYNOS_DRM_OPS_DST].degree = degree;
97                 property->config[EXYNOS_DRM_OPS_DST].fmt = DRM_FORMAT_XRGB8888;
98                 if (property->config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_90) {
99                         dst_sz.hsize = def_sz->vsize;
100                         dst_sz.vsize = def_sz->hsize;
101
102                         scale_pos.w = def_sz->vsize;
103                         scale_pos.h = def_sz->hsize;
104                 }
105                 property->config[EXYNOS_DRM_OPS_DST].pos = scale_pos;
106                 property->config[EXYNOS_DRM_OPS_DST].sz = dst_sz;
107                 break;
108         case IPP_CMD_OUTPUT:
109         default:
110                 ret = -EINVAL;
111                 return ret;
112         }
113
114         ret = ioctl(fd, DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY, property);
115         if (ret)
116                 fprintf(stderr,
117                         "failed to DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY : %s\n",
118                         strerror(errno));
119         
120         printf("DRM_IOCTL_EXYNOS_IPP_SET_PROPERTY : prop_id[%d]\n",
121                 property->prop_id);
122
123         return ret;
124 }
125
126 static int exynos_drm_ipp_queue_buf(int fd, struct drm_exynos_ipp_queue_buf *qbuf,
127                                         enum drm_exynos_ops_id ops_id,
128                                         enum drm_exynos_ipp_buf_type buf_type,
129                                         int prop_id,
130                                         int buf_id,
131                                         unsigned int gem_handle)
132 {
133         int ret = 0;
134
135         memset(qbuf, 0x00, sizeof(struct drm_exynos_ipp_queue_buf));
136
137         qbuf->ops_id = ops_id;
138         qbuf->buf_type = buf_type;
139         qbuf->user_data = 0;
140         qbuf->prop_id = prop_id;
141         qbuf->buf_id = buf_id;
142         qbuf->handle[EXYNOS_DRM_PLANAR_Y] = gem_handle;
143         qbuf->handle[EXYNOS_DRM_PLANAR_CB] = 0;
144         qbuf->handle[EXYNOS_DRM_PLANAR_CR] = 0;
145
146         ret = ioctl(fd, DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF, qbuf);
147         if (ret)
148                 fprintf(stderr,
149                 "failed to DRM_IOCTL_EXYNOS_IPP_QUEUE_BUF[id:%d][buf_type:%d] : %s\n",
150                 ops_id, buf_type, strerror(errno));
151  
152         return ret;
153 }
154
155 static int exynos_drm_ipp_cmd_ctrl(int fd, struct drm_exynos_ipp_cmd_ctrl *cmd_ctrl,
156                                 int prop_id,
157                                 enum drm_exynos_ipp_ctrl ctrl)
158 {
159         int ret = 0;
160
161         memset(cmd_ctrl, 0x00, sizeof(struct drm_exynos_ipp_cmd_ctrl));
162
163         cmd_ctrl->prop_id = prop_id;
164         cmd_ctrl->ctrl = ctrl;
165
166         ret = ioctl(fd, DRM_IOCTL_EXYNOS_IPP_CMD_CTRL, cmd_ctrl);
167         if (ret)
168                 fprintf(stderr,
169                 "failed to DRM_IOCTL_EXYNOS_IPP_CMD_CTRL[prop_id:%d][ctrl:%d] : %s\n",
170                 prop_id, ctrl, strerror(errno));
171
172         return ret;
173 }
174
175 int fimc_event_handler(struct drm_exynos_ipp_queue_buf *src_qbuf, struct drm_exynos_gem_create *src_gem,
176         struct drm_exynos_ipp_queue_buf *dst_qbuf, struct drm_exynos_gem_create *dst_gem,
177         struct drm_exynos_ipp_property *property, void **usr_addr,
178         unsigned int width, unsigned int height, enum drm_exynos_ipp_cmd cmd)
179 {
180         char buffer[1024];
181         int len, i;
182         struct drm_event *e;
183         struct drm_exynos_ipp_event *ipp_event;
184         char filename[100];
185         int ret = 0;
186         int src_buf_id, dst_buf_id;
187         static bmp_idx = 0;
188
189         len = read(fd, buffer, sizeof buffer);
190         if (len == 0)
191                 return 0;
192         if (len < sizeof *e)
193                 return -1;
194
195         i = 0;
196         while (i < len) {
197                 e = (struct drm_event *) &buffer[i];
198                 switch (e->type) {
199                 case DRM_EXYNOS_IPP_EVENT:
200                         ipp_event = (struct drm_exynos_ipp_event *) e;
201                         src_buf_id = ipp_event->buf_id[EXYNOS_DRM_OPS_SRC];
202                         dst_buf_id = ipp_event->buf_id[EXYNOS_DRM_OPS_DST];
203
204                         printf("%s:src_buf_id[%d]dst_buf_id[%d]bmp_idx[%d]\n", __func__, src_buf_id, dst_buf_id, bmp_idx++);
205                         if (cmd == IPP_CMD_M2M) {
206                                 sprintf(filename, "/opt/media/fimc_m2m_dst%d.bmp", bmp_idx);
207
208                                 util_write_bmp(filename, usr_addr[dst_buf_id], width, height);
209
210                                 /* For source buffer queue to IPP */
211                                 ret = exynos_drm_ipp_queue_buf(fd, &src_qbuf[src_buf_id], EXYNOS_DRM_OPS_SRC,
212                                                         IPP_BUF_ENQUEUE, property->prop_id,
213                                                         src_buf_id, src_gem[src_buf_id].handle);
214                                 if (ret) {
215                                         fprintf(stderr, "failed to ipp buf src queue\n");
216                                         goto err_ipp_ctrl_close;
217                                 }
218
219                                 /* For destination buffer queue to IPP */
220                                 ret = exynos_drm_ipp_queue_buf(fd, &dst_qbuf[dst_buf_id], EXYNOS_DRM_OPS_DST,
221                                                         IPP_BUF_ENQUEUE, property->prop_id,
222                                                         dst_buf_id, dst_gem[dst_buf_id].handle);
223                                 if (ret) {
224                                         fprintf(stderr, "failed to ipp buf dst queue\n");
225                                         goto err_ipp_ctrl_close;
226                                 }
227                         } else if (cmd == IPP_CMD_WB) {
228                                 sprintf(filename, "/opt/media/fimc_wb_%d.bmp", bmp_idx);
229
230                                 util_write_bmp(filename, usr_addr[dst_buf_id], width, height);
231                         
232                                 /* For destination buffer queue to IPP */
233                                 ret = exynos_drm_ipp_queue_buf(fd, &dst_qbuf[dst_buf_id], EXYNOS_DRM_OPS_DST,
234                                                         IPP_BUF_ENQUEUE, property->prop_id,
235                                                         dst_buf_id, dst_gem[dst_buf_id].handle);
236                                 if (ret) {
237                                         fprintf(stderr, "failed to ipp buf dst queue\n");
238                                         goto err_ipp_ctrl_close;
239                                 }
240                         }
241                         break;
242                 default:
243                         break;
244                 }
245                 i += e->length;
246         }
247
248 err_ipp_ctrl_close:
249         return ret;
250 }
251
252 void fimc_m2m_set_mode(struct connector *c, int count, int page_flip,
253                                                                 long int *usec)
254 {
255         struct drm_exynos_ipp_property property;
256         struct drm_exynos_ipp_cmd_ctrl cmd_ctrl;
257         struct drm_exynos_sz def_sz = {720, 1280};
258         struct drm_exynos_ipp_queue_buf qbuf1[MAX_BUF], qbuf2[MAX_BUF];
259         unsigned int width=720, height=1280, stride;
260         int ret, i, j, x;
261         struct drm_exynos_gem_create gem1[MAX_BUF], gem2[MAX_BUF];
262         struct drm_exynos_gem_mmap mmap1[MAX_BUF], mmap2[MAX_BUF];
263         void *usr_addr1[MAX_BUF], *usr_addr2[MAX_BUF];
264         struct timeval begin, end;
265         struct drm_gem_close args;
266         char filename[100];
267
268         /* For mode */
269         width = height = 0;
270         for (i = 0; i < count; i++) {
271                 connector_find_mode(&c[i]);
272                 if (c[i].mode == NULL) continue;
273                 width += c[i].mode->hdisplay;
274                 if (height < c[i].mode->vdisplay) height = c[i].mode->vdisplay;
275         }
276         stride = width * 4;    
277         i =0;
278
279         def_sz.hsize = width;
280         def_sz.vsize = height;
281
282         /* For property */
283         ret = exynos_drm_ipp_set_property(fd, &property, &def_sz, IPP_CMD_M2M, EXYNOS_DRM_DEGREE_90);
284         if (ret) {
285                 fprintf(stderr, "failed to ipp property\n");
286                 return;
287         }
288
289         for (i = 0; i < MAX_BUF; i++) {
290                 /* For source buffer */
291                 ret = util_gem_create_mmap(fd, &gem1[i], &mmap1[i], stride * height);
292                 if (ret) {
293                         fprintf(stderr, "failed to gem create mmap: %s\n",
294                         strerror(errno));
295
296                         if (ret == -1)
297                                 return;
298                         else if (ret == -2)
299                                 goto err_ipp_ctrl_close;
300                 }
301                 usr_addr1[i] = (void *)(unsigned long)mmap1[i].mapped;
302
303                 /* For source buffer map to IPP */
304                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf1[i], EXYNOS_DRM_OPS_SRC,
305                                 IPP_BUF_ENQUEUE, property.prop_id, i, gem1[i].handle);
306                 if (ret) {
307                         fprintf(stderr, "failed to ipp buf src map\n");
308                         goto err_ipp_ctrl_close;
309                 }
310
311                 util_draw_buffer(usr_addr1[i], 1, width, height, stride, 0);
312                 sprintf(filename, "/opt/media/fimc_m2m_org_src%d.bmp", j);
313                 util_write_bmp(filename, usr_addr1[i], width, height);
314         }
315
316         for (i = 0; i < MAX_BUF; i++) {
317                 /* For destination buffer */
318                 ret = util_gem_create_mmap(fd, &gem2[i], &mmap2[i], stride * height);
319                 if (ret) {
320                         fprintf(stderr, "failed to gem create mmap: %s\n",
321                                                 strerror(errno));
322                         if (ret == -1)
323                                 goto err_ipp_ctrl_close;
324                         else if (ret == -2)
325                                 goto err_ipp_ctrl_close;
326                 }
327                 usr_addr2[i] = (void*)(unsigned long)mmap2[i].mapped;
328
329                 /* For destination buffer map to IPP */
330                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf2[i], EXYNOS_DRM_OPS_DST,
331                         IPP_BUF_ENQUEUE, property.prop_id, i, gem2[i].handle);
332                 if (ret) {
333                         fprintf(stderr, "failed to ipp buf dst map\n");
334                         goto err_ipp_ctrl_close;
335                 }
336
337                 util_draw_buffer(usr_addr2[i], 0, 0, 0, 0, mmap2[i].size);
338                 sprintf(filename, "/opt/media/fimc_m2m_org_dst%d.bmp", j);
339                 util_write_bmp(filename, usr_addr2[i], height, width);
340         }
341
342         /* Start */
343         gettimeofday(&begin, NULL);
344         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_PLAY);
345         if (ret) {
346                 fprintf(stderr,
347                 "failed to ipp ctrl IPP_CMD_M2M start\n");
348                 goto err_ipp_ctrl_close;
349         }
350         
351         j=0;
352         while (1) {
353                 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
354                 fd_set fds;
355
356                 FD_ZERO(&fds);
357                 FD_SET(0, &fds);
358                 FD_SET(fd, &fds);
359                 ret = select(fd + 1, &fds, NULL, NULL, &timeout);
360                 if (ret <= 0) {
361                         fprintf(stderr, "select timed out or error.\n");
362                         continue;
363                 } else if (FD_ISSET(0, &fds)) {
364                         break;
365                 }
366
367                 gettimeofday(&end, NULL);
368                 usec[j] = (end.tv_sec - begin.tv_sec) * 1000000 +
369                 (end.tv_usec - begin.tv_usec);
370
371                 if (property.config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_90 ||
372                         property.config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_270) {
373                         if(fimc_event_handler(qbuf1, gem1, qbuf2, gem2, &property, usr_addr2, height, width, IPP_CMD_M2M) < 0)
374                                 break;
375                 } else {
376                         if(fimc_event_handler(qbuf1, gem1, qbuf2, gem2, &property, usr_addr2, width, height, IPP_CMD_M2M) < 0)
377                                 break;
378                 }
379
380                 if (++j > MAX_LOOP)
381                         break;
382
383                 gettimeofday(&begin, NULL);
384         }
385
386 err_ipp_ctrl_close:
387         /* For source buffer dequeue to IPP */
388         for (i = 0; i < MAX_BUF; i++) {
389                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf1[i], EXYNOS_DRM_OPS_SRC,
390                                                 IPP_BUF_DEQUEUE, property.prop_id, i, gem1[i].handle);
391                 if (ret < 0)
392                         fprintf(stderr, "failed to ipp buf dst dequeue\n");
393         }
394
395         /* For destination buffer dequeue to IPP */
396         for (i = 0; i < MAX_BUF; i++) {
397                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf2[i], EXYNOS_DRM_OPS_DST,
398                                                 IPP_BUF_DEQUEUE, property.prop_id, i, gem2[i].handle);
399                 if (ret < 0)
400                         fprintf(stderr, "failed to ipp buf dst dequeue\n");
401         }
402
403         /* Stop */
404         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_STOP);
405         if (ret)
406                 fprintf(stderr, "failed to ipp ctrl IPP_CMD_WB stop\n");
407
408         /* Close source buffer */
409         for (i = 0; i < MAX_BUF; i++) {
410                 munmap(usr_addr1[i], mmap1[i].size);
411                 memset(&args, 0x00, sizeof(struct drm_gem_close));
412                 args.handle = gem1[i].handle;
413                 exynos_gem_close(fd, &args);
414         }
415
416         /* Close destination buffer */
417         for (i = 0; i < MAX_BUF; i++) {
418                 munmap(usr_addr2[i], mmap2[i].size);
419                 memset(&args, 0x00, sizeof(struct drm_gem_close));
420                 args.handle = gem2[i].handle;
421                 exynos_gem_close(fd, &args);
422         }
423
424         return;
425 }
426
427 void fimc_wb_set_mode(struct connector *c, int count, int page_flip,
428                                                                 long int *usec)
429 {
430         struct drm_exynos_pos def_pos = {0, 0, 720, 1280};
431         struct drm_exynos_sz def_sz = {720, 1280};
432         struct drm_exynos_ipp_property property;
433         struct drm_exynos_gem_create gem[MAX_BUF];
434         struct drm_exynos_gem_mmap mmap[MAX_BUF];
435         struct drm_exynos_ipp_queue_buf qbuf[MAX_BUF];  
436         void *usr_addr[MAX_BUF];
437         struct drm_exynos_ipp_cmd_ctrl cmd_ctrl;
438         unsigned int width, height, stride;
439         int ret, i, j;
440         struct timeval begin, end;
441         struct drm_gem_close args;
442
443         /* For mode */
444         width = height = 0;
445         for (i = 0; i < count; i++) {
446                 connector_find_mode(&c[i]);
447                 if (c[i].mode == NULL) continue;
448                 width += c[i].mode->hdisplay;
449                 if (height < c[i].mode->vdisplay) height = c[i].mode->vdisplay;
450         }
451         stride = width * 4;
452
453         def_sz.hsize = width;
454         def_sz.vsize = height;
455
456         /* For property */
457         ret = exynos_drm_ipp_set_property(fd, &property, &def_sz, IPP_CMD_WB, EXYNOS_DRM_DEGREE_0);
458         if (ret) {
459                 fprintf(stderr, "failed to ipp property\n");
460                 return;
461         }
462
463         /* For destination buffer */
464         for (i = 0; i < MAX_BUF; i++) {
465                 ret = util_gem_create_mmap(fd, &gem[i], &mmap[i], stride * height);
466                 if (ret) {
467                         fprintf(stderr, "failed to gem create mmap: %s\n",
468                                                                 strerror(errno));
469                         if (ret == -1) return;
470                         else if (ret == -2) goto err_ipp_ctrl_close;
471                 }
472                 usr_addr[i] = (void *)(unsigned long)mmap[i].mapped;
473                 /* For destination buffer map to IPP */
474                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf[i], EXYNOS_DRM_OPS_DST,
475                                                 IPP_BUF_ENQUEUE, property.prop_id, i, gem[i].handle);
476                 if (ret) {
477                         fprintf(stderr, "failed to ipp buf dst map\n");
478                         goto err_ipp_ctrl_close;
479                 }
480         }
481
482         /* Start */
483         gettimeofday(&begin, NULL);
484         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_PLAY);
485         if (ret) {
486                 fprintf(stderr,
487                         "failed to ipp ctrl IPP_CMD_WB start\n");
488                 goto err_ipp_ctrl_close;
489         }
490
491         j = 0;
492         while (1) {
493                 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
494                 fd_set fds;
495
496                 FD_ZERO(&fds);
497                 FD_SET(0, &fds);
498                 FD_SET(fd, &fds);
499                 ret = select(fd + 1, &fds, NULL, NULL, &timeout);
500                 if (ret <= 0) {
501                         fprintf(stderr, "select timed out or error.\n");
502                         continue;
503                 } else if (FD_ISSET(0, &fds)) {
504                         fprintf(stderr, "select error.\n");
505                         break;
506                 }
507
508                 gettimeofday(&end, NULL);
509                 usec[j] = (end.tv_sec - begin.tv_sec) * 1000000 +
510                                         (end.tv_usec - begin.tv_usec);
511
512                 if (property.config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_90 ||
513                         property.config[EXYNOS_DRM_OPS_DST].degree == EXYNOS_DRM_DEGREE_270 ||
514                         property.config[EXYNOS_DRM_OPS_SRC].degree == EXYNOS_DRM_DEGREE_90 ||
515                         property.config[EXYNOS_DRM_OPS_SRC].degree == EXYNOS_DRM_DEGREE_270) {
516                         if(fimc_event_handler(NULL, NULL, qbuf, gem, &property, usr_addr, height, width, IPP_CMD_WB) < 0)
517                                 break;
518                 } else {
519                         if(fimc_event_handler(NULL, NULL, qbuf, gem, &property, usr_addr, width, height, IPP_CMD_WB) < 0)
520                                 break;
521                 }
522
523                 if (++j > MAX_LOOP)
524                         break;
525
526                 if (j == HALF_LOOP) {
527                         /* Stop */
528                         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_STOP);
529                         if (ret) {
530                                 fprintf(stderr, "failed to ipp ctrl IPP_CMD_WB stop\n");
531                                 goto err_ipp_ctrl_close;
532                         }
533
534                         /* For property */
535                         ret = exynos_drm_ipp_set_property(fd, &property, &def_sz, IPP_CMD_WB, EXYNOS_DRM_DEGREE_90);
536                         if (ret) {
537                                 fprintf(stderr, "failed to ipp property\n");
538                                 goto err_ipp_ctrl_close;
539                         }
540
541                         /* For destination buffer */
542                         for (i = 0; i < MAX_BUF; i++) {
543                                 /* For destination buffer map to IPP */
544                                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf[i], EXYNOS_DRM_OPS_DST,
545                                                                 IPP_BUF_ENQUEUE, property.prop_id, i, gem[i].handle);
546                                 if (ret) {
547                                         fprintf(stderr, "failed to ipp buf dst map\n");
548                                         goto err_ipp_ctrl_close;
549                                 }
550                         }
551
552                         /* Start */
553                         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_PLAY);
554                         if (ret) {
555                                 fprintf(stderr,
556                                         "failed to ipp ctrl IPP_CMD_WB start\n");
557                                 goto err_ipp_ctrl_close;
558                         }
559                 }
560
561                 gettimeofday(&begin, NULL);
562         }
563
564 err_ipp_ctrl_close:
565         /* For destination buffer dequeue to IPP */
566         for (i = 0; i < MAX_BUF; i++) {
567                 ret = exynos_drm_ipp_queue_buf(fd, &qbuf[i], EXYNOS_DRM_OPS_DST,
568                                                 IPP_BUF_DEQUEUE, property.prop_id, i, gem[i].handle);
569                 if (ret < 0)
570                         fprintf(stderr, "failed to ipp buf dst dequeue\n");
571         }
572
573         /* Stop */
574         ret = exynos_drm_ipp_cmd_ctrl(fd, &cmd_ctrl, property.prop_id, IPP_CTRL_STOP);
575         if (ret)
576                 fprintf(stderr, "failed to ipp ctrl IPP_CMD_WB stop\n");
577
578         for (i = 0; i < MAX_BUF; i++) {
579                 munmap(usr_addr[i], mmap[i].size);
580                 memset(&args, 0x00, sizeof(struct drm_gem_close));
581                 args.handle = gem[i].handle;
582                 exynos_gem_close(fd, &args);
583         }
584
585         return;
586 }
587
588 void fimc_output_set_mode(struct connector *c, int count, int page_flip,
589                                                                 long int *usec)
590 {
591         fprintf(stderr, "not supported. please wait v2\n");
592 }
593