• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  *
19  * @author Rama, Meka(v.meka@samsung.com)
20            Sangwoo, Park(sw5771.park@samsung.com)
21            Jamie Oh (jung-min.oh@samsung.com)
22  * @date   2011-07-28
23  *
24  */
25 
26 #include "SecHWCUtils.h"
27 
window_open(struct hwc_win_info_t * win,int id)28 int window_open(struct hwc_win_info_t *win, int id)
29 {
30     char name[64];
31 
32     char const * const device_template = "/dev/graphics/fb%u";
33     /* window & FB maping
34        fb0 -> win-id : 2
35        fb1 -> win-id : 3
36        fb2 -> win-id : 4
37        fb3 -> win-id : 0
38        fb4 -> win_id : 1
39        it is pre assumed that ...win0 or win1 is used here..
40 	 */
41     switch (id) {
42     case 0:
43     case 1:
44     case 2:
45         break;
46     default:
47         ALOGE("%s::id(%d) is weird", __func__, id);
48         goto error;
49     }
50 
51     snprintf(name, 64, device_template, (id + 3)%5);
52 
53     win->fd = open(name, O_RDWR);
54     if (win->fd < 0) {
55 		ALOGE("%s::Failed to open window device (%s) : %s",
56 				__func__, strerror(errno), device_template);
57         goto error;
58     }
59 
60     return 0;
61 
62 error:
63     if (0 <= win->fd)
64         close(win->fd);
65     win->fd = -1;
66 
67     return -1;
68 }
69 
window_close(struct hwc_win_info_t * win)70 int window_close(struct hwc_win_info_t *win)
71 {
72     int ret = 0;
73 
74     if (0 <= win->fd)
75         ret = close(win->fd);
76     win->fd = -1;
77 
78     return ret;
79 }
80 
window_set_pos(struct hwc_win_info_t * win)81 int window_set_pos(struct hwc_win_info_t *win)
82 {
83     struct secfb_user_window window;
84 
85     /* before changing the screen configuration...powerdown the window */
86     if(window_hide(win) != 0)
87         return -1;
88 
89     win->var_info.xres = win->rect_info.w;
90     win->var_info.yres = win->rect_info.h;
91 
92     win->var_info.activate &= ~FB_ACTIVATE_MASK;
93     win->var_info.activate |= FB_ACTIVATE_FORCE;
94 
95     if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) {
96         ALOGE("%s::FBIOPUT_VSCREENINFO(%d, %d) fail",
97           		__func__, win->rect_info.w, win->rect_info.h);
98         return -1;
99     }
100 
101     window.x = win->rect_info.x;
102     window.y = win->rect_info.y;
103 
104     if (ioctl(win->fd, SECFB_WIN_POSITION, &window) < 0) {
105         ALOGE("%s::S3CFB_WIN_POSITION(%d, %d) fail",
106             	__func__, window.x, window.y);
107       return -1;
108     }
109 
110     return 0;
111 }
112 
window_get_info(struct hwc_win_info_t * win)113 int window_get_info(struct hwc_win_info_t *win)
114 {
115     if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
116         ALOGE("FBIOGET_FSCREENINFO failed : %s", strerror(errno));
117         goto error;
118     }
119 
120     return 0;
121 
122 error:
123     win->fix_info.smem_start = 0;
124 
125     return -1;
126 }
127 
window_pan_display(struct hwc_win_info_t * win)128 int window_pan_display(struct hwc_win_info_t *win)
129 {
130     struct fb_var_screeninfo *lcd_info = &(win->lcd_info);
131 
132     lcd_info->yoffset = lcd_info->yres * win->buf_index;
133 
134     if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) {
135         ALOGE("%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)",
136             	__func__, lcd_info->yres, win->buf_index, lcd_info->yres_virtual,
137             strerror(errno));
138         return -1;
139     }
140     return 0;
141 }
142 
window_show(struct hwc_win_info_t * win)143 int window_show(struct hwc_win_info_t *win)
144 {
145     if(win->power_state == 0) {
146         if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
147             ALOGE("%s: FBIOBLANK failed : (%d:%s)", __func__, win->fd,
148                     strerror(errno));
149             return -1;
150         }
151         win->power_state = 1;
152     }
153     return 0;
154 }
155 
window_hide(struct hwc_win_info_t * win)156 int window_hide(struct hwc_win_info_t *win)
157 {
158     if (win->power_state == 1) {
159         if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
160             ALOGE("%s::FBIOBLANK failed : (%d:%s)",
161              		__func__, win->fd, strerror(errno));
162             return -1;
163         }
164         win->power_state = 0;
165     }
166     return 0;
167 }
168 
window_get_global_lcd_info(struct hwc_context_t * ctx)169 int window_get_global_lcd_info(struct hwc_context_t *ctx)
170 {
171     struct hwc_win_info_t win;
172     int ret = 0;
173 
174     if (ioctl(ctx->global_lcd_win.fd, FBIOGET_VSCREENINFO, &ctx->lcd_info) < 0) {
175         ALOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
176         return -1;
177     }
178 
179     if (ctx->lcd_info.xres == 0) {
180         ctx->lcd_info.xres = DEFAULT_LCD_WIDTH;
181         ctx->lcd_info.xres_virtual = DEFAULT_LCD_WIDTH;
182     }
183 
184     if (ctx->lcd_info.yres == 0) {
185         ctx->lcd_info.yres = DEFAULT_LCD_HEIGHT;
186         ctx->lcd_info.yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
187     }
188 
189     if (ctx->lcd_info.bits_per_pixel == 0)
190         ctx->lcd_info.bits_per_pixel = DEFAULT_LCD_BPP;
191 
192     return 0;
193 }
194 
fimc_v4l2_set_src(int fd,unsigned int hw_ver,s5p_fimc_img_info * src)195 int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
196 {
197     struct v4l2_format  fmt;
198     struct v4l2_cropcap cropcap;
199     struct v4l2_crop    crop;
200     struct v4l2_requestbuffers req;
201 
202     /*
203      * To set size & format for source image (DMA-INPUT)
204      */
205     fmt.type                = V4L2_BUF_TYPE_VIDEO_OUTPUT;
206     fmt.fmt.pix.width       = src->full_width;
207     fmt.fmt.pix.height      = src->full_height;
208     fmt.fmt.pix.pixelformat = src->color_space;
209     fmt.fmt.pix.field       = V4L2_FIELD_NONE;
210 
211     if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) {
212         ALOGE("VIDIOC_S_FMT failed : errno=%d (%s) : fd=%d", errno,
213                 strerror(errno), fd);
214         return -1;
215     }
216 
217     /*
218      * crop input size
219      */
220     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
221     if (0x50 == hw_ver) {
222         crop.c.left   = src->start_x;
223         crop.c.top    = src->start_y;
224     } else {
225         crop.c.left   = 0;
226         crop.c.top    = 0;
227     }
228     crop.c.width  = src->width;
229     crop.c.height = src->height;
230     if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
231         ALOGE("Error in video VIDIOC_S_CROP (%d, %d, %d, %d)",
232                 crop.c.left, crop.c.top, crop.c.width, crop.c.height);
233         return -1;
234     }
235 
236     /*
237      * input buffer type
238      */
239     req.count       = 1;
240     req.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
241     req.memory      = V4L2_MEMORY_USERPTR;
242 
243     if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
244         ALOGE("Error in VIDIOC_REQBUFS");
245         return -1;
246     }
247 
248     return 0;
249 }
250 
fimc_v4l2_set_dst(int fd,s5p_fimc_img_info * dst,int rotation,int flag_h_flip,int flag_v_flip,unsigned int addr)251 int fimc_v4l2_set_dst(int fd,
252                       s5p_fimc_img_info *dst,
253                       int rotation,
254                       int flag_h_flip,
255                       int flag_v_flip,
256                       unsigned int addr)
257 {
258     struct v4l2_format      sFormat;
259     struct v4l2_control     vc;
260     struct v4l2_framebuffer fbuf;
261 
262     /*
263      * set rotation configuration
264      */
265     vc.id = V4L2_CID_HFLIP;
266     vc.value = flag_h_flip;
267     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
268         ALOGE("Error in video VIDIOC_S_CTRL - flag_h_flip (%d)", flag_h_flip);
269         return -1;
270     }
271 
272     vc.id = V4L2_CID_VFLIP;
273     vc.value = flag_v_flip;
274     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
275         ALOGE("Error in video VIDIOC_S_CTRL - flag_v_flip (%d)", flag_v_flip);
276         return -1;
277     }
278 
279     vc.id = V4L2_CID_ROTATION;
280     vc.value = rotation;
281     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
282         ALOGE("Error in video VIDIOC_S_CTRL - rotation (%d)", rotation);
283         return -1;
284     }
285 
286     /*
287      * set size, format & address for destination image (DMA-OUTPUT)
288      */
289     if (ioctl (fd, VIDIOC_G_FBUF, &fbuf) < 0) {
290         ALOGE("Error in video VIDIOC_G_FBUF");
291         return -1;
292     }
293 
294     fbuf.base            = (void *)addr;
295     fbuf.fmt.width       = dst->full_width;
296     fbuf.fmt.height      = dst->full_height;
297     fbuf.fmt.pixelformat = dst->color_space;
298     if (ioctl (fd, VIDIOC_S_FBUF, &fbuf) < 0) {
299         ALOGE("Error in video VIDIOC_S_FBUF 0x%x %d %d %d",
300                 (void *)addr, dst->full_width, dst->full_height,
301                 dst->color_space);
302         return -1;
303     }
304 
305     /*
306      * set destination window
307      */
308     sFormat.type             = V4L2_BUF_TYPE_VIDEO_OVERLAY;
309     sFormat.fmt.win.w.left   = dst->start_x;
310     sFormat.fmt.win.w.top    = dst->start_y;
311     sFormat.fmt.win.w.width  = dst->width;
312     sFormat.fmt.win.w.height = dst->height;
313     if (ioctl(fd, VIDIOC_S_FMT, &sFormat) < 0) {
314         ALOGE("Error in video VIDIOC_S_FMT %d %d %d %d",
315                 dst->start_x, dst->start_y, dst->width, dst->height);
316         return -1;
317     }
318 
319     return 0;
320 }
321 
fimc_v4l2_stream_on(int fd,enum v4l2_buf_type type)322 int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
323 {
324     if (ioctl (fd, VIDIOC_STREAMON, &type) < 0) {
325         ALOGE("Error in VIDIOC_STREAMON");
326         return -1;
327     }
328 
329     return 0;
330 }
331 
fimc_v4l2_queue(int fd,struct fimc_buf * fimc_buf)332 int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf)
333 {
334     struct v4l2_buffer buf;
335 
336     buf.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
337     buf.memory      = V4L2_MEMORY_USERPTR;
338     buf.m.userptr   = (unsigned long)fimc_buf;
339     buf.length      = 0;
340     buf.index       = 0;
341 
342     if (ioctl (fd, VIDIOC_QBUF, &buf) < 0) {
343         ALOGE("Error in VIDIOC_QBUF");
344         return -1;
345     }
346 
347     return 0;
348 }
349 
fimc_v4l2_dequeue(int fd)350 int fimc_v4l2_dequeue(int fd)
351 {
352     struct v4l2_buffer buf;
353 
354     buf.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
355     buf.memory      = V4L2_MEMORY_USERPTR;
356 
357     if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) {
358         ALOGE("Error in VIDIOC_DQBUF");
359         return -1;
360     }
361 
362     return buf.index;
363 }
364 
fimc_v4l2_stream_off(int fd)365 int fimc_v4l2_stream_off(int fd)
366 {
367     enum v4l2_buf_type type;
368     type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
369 
370     if (ioctl (fd, VIDIOC_STREAMOFF, &type) < 0) {
371         ALOGE("Error in VIDIOC_STREAMOFF");
372         return -1;
373     }
374 
375     return 0;
376 }
377 
fimc_v4l2_clr_buf(int fd)378 int fimc_v4l2_clr_buf(int fd)
379 {
380     struct v4l2_requestbuffers req;
381 
382     req.count   = 0;
383     req.type    = V4L2_BUF_TYPE_VIDEO_OUTPUT;
384     req.memory  = V4L2_MEMORY_USERPTR;
385 
386     if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
387         ALOGE("Error in VIDIOC_REQBUFS");
388     }
389 
390     return 0;
391 }
392 
fimc_handle_oneshot(int fd,struct fimc_buf * fimc_buf)393 int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf)
394 {
395     int ret =0;
396 
397     if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT) < 0) {
398         ALOGE("Fail : v4l2_stream_on()");
399         return -1;
400     }
401 
402     if (fimc_v4l2_queue(fd, fimc_buf) < 0) {
403         ALOGE("Fail : v4l2_queue()");
404         ret = -1;
405         goto stream_off;
406     }
407 
408     if (fimc_v4l2_dequeue(fd) < 0) {
409         ALOGE("Fail : v4l2_dequeue()");
410         ret = -1;
411         goto stream_off;
412     }
413 
414 stream_off:
415     if (fimc_v4l2_stream_off(fd) < 0) {
416         ALOGE("Fail : v4l2_stream_off()");
417         return -1;
418     }
419 
420     if (fimc_v4l2_clr_buf(fd) < 0) {
421         ALOGE("Fail : v4l2_clr_buf()");
422         return -1;
423     }
424 
425     return ret;
426 }
427 
get_src_phys_addr(struct hwc_context_t * ctx,sec_img * src_img,unsigned int * phyAddr)428 static int get_src_phys_addr(struct hwc_context_t *ctx,
429                              sec_img *src_img,
430                              unsigned int *phyAddr)
431 {
432     s5p_fimc_t *fimc = &ctx->fimc;
433 
434    if(src_img->mem_type == HWC_PHYS_MEM_TYPE) {
435         switch(src_img->format) {
436         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
437             fimc->params.src.buf_addr_phy_rgb_y = phyAddr[0];
438             fimc->params.src.buf_addr_phy_cb    = phyAddr[1];
439             break;
440         default:
441             ALOGE("%s format error (format=0x%x)", __func__,
442                     src_img->format);
443             return -1;
444         }
445     } else {
446         ALOGE("%s mem_type error (mem_type=%d)", __func__, src_img->mem_type);
447         return -1;
448     }
449 
450     return 0;
451 }
452 
get_dst_phys_addr(struct hwc_context_t * ctx,sec_img * dst_img)453 static int get_dst_phys_addr(struct hwc_context_t *ctx,
454                              sec_img *dst_img)
455 {
456     unsigned int dst_phys_addr  = 0;
457 
458     if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
459         dst_phys_addr = dst_img->base;
460     else {
461         ALOGE("%s::get_dst_phys_addr fail ", __func__);
462         dst_phys_addr = 0;
463     }
464     return dst_phys_addr;
465 }
466 
rotateValueHAL2PP(unsigned char transform,int * flag_h_flip,int * flag_v_flip)467 static inline int rotateValueHAL2PP(unsigned char transform,
468                                     int *flag_h_flip,
469                                     int *flag_v_flip)
470 {
471     int rotate_result = 0;
472     int rotate_flag = transform & 0x7;
473 
474     switch (rotate_flag) {
475     case HAL_TRANSFORM_ROT_90:
476         rotate_result = 90;
477         break;
478     case HAL_TRANSFORM_ROT_180:
479         rotate_result = 180;
480         break;
481     case HAL_TRANSFORM_ROT_270:
482         rotate_result = 270;
483         break;
484     }
485 
486     switch (rotate_flag) {
487     case HAL_TRANSFORM_FLIP_H:
488         *flag_h_flip = 1;
489         *flag_v_flip = 0;
490         break;
491     case HAL_TRANSFORM_FLIP_V:
492         *flag_h_flip = 0;
493         *flag_v_flip = 1;
494         break;
495     default:
496         *flag_h_flip = 0;
497         *flag_v_flip = 0;
498         break;
499     }
500 
501     return rotate_result;
502 }
503 
multipleOfN(int number,int N)504 static inline int multipleOfN(int number, int N)
505 {
506     int result = number;
507     switch (N) {
508     case 1:
509     case 2:
510     case 4:
511     case 8:
512     case 16:
513     case 32:
514     case 64:
515     case 128:
516     case 256:
517         result = (number - (number & (N-1)));
518         break;
519     default:
520         result = number - (number % N);
521         break;
522     }
523     return result;
524 }
525 
widthOfPP(unsigned int ver,int pp_color_format,int number)526 static inline int widthOfPP(unsigned int ver,
527                             int pp_color_format,
528                             int number)
529 {
530     if (0x50 == ver) {
531         switch(pp_color_format) {
532         /* 422 1/2/3 plane */
533         case V4L2_PIX_FMT_YUYV:
534         case V4L2_PIX_FMT_UYVY:
535         case V4L2_PIX_FMT_NV61:
536         case V4L2_PIX_FMT_NV16:
537         case V4L2_PIX_FMT_YUV422P:
538 
539         /* 420 2/3 plane */
540         case V4L2_PIX_FMT_NV21:
541         case V4L2_PIX_FMT_NV12:
542         case V4L2_PIX_FMT_NV12T:
543         case V4L2_PIX_FMT_YUV420:
544             return multipleOfN(number, 2);
545 
546         default :
547             return number;
548         }
549     } else {
550         switch(pp_color_format) {
551         case V4L2_PIX_FMT_RGB565:
552             return multipleOfN(number, 8);
553 
554         case V4L2_PIX_FMT_RGB32:
555             return multipleOfN(number, 4);
556 
557         case V4L2_PIX_FMT_YUYV:
558         case V4L2_PIX_FMT_UYVY:
559             return multipleOfN(number, 4);
560 
561         case V4L2_PIX_FMT_NV61:
562         case V4L2_PIX_FMT_NV16:
563             return multipleOfN(number, 8);
564 
565         case V4L2_PIX_FMT_YUV422P:
566             return multipleOfN(number, 16);
567 
568         case V4L2_PIX_FMT_NV21:
569         case V4L2_PIX_FMT_NV12:
570         case V4L2_PIX_FMT_NV12T:
571             return multipleOfN(number, 8);
572 
573         case V4L2_PIX_FMT_YUV420:
574             return multipleOfN(number, 16);
575 
576         default :
577             return number;
578         }
579     }
580     return number;
581 }
582 
heightOfPP(int pp_color_format,int number)583 static inline int heightOfPP(int pp_color_format,
584                              int number)
585 {
586     switch(pp_color_format) {
587     case V4L2_PIX_FMT_NV21:
588     case V4L2_PIX_FMT_NV12:
589     case V4L2_PIX_FMT_NV12T:
590     case V4L2_PIX_FMT_YUV420:
591         return multipleOfN(number, 2);
592 
593     default :
594         return number;
595     }
596     return number;
597 }
598 
runcFimcCore(struct hwc_context_t * ctx,sec_img * src_img,sec_rect * src_rect,uint32_t src_color_space,unsigned int dst_phys_addr,sec_img * dst_img,sec_rect * dst_rect,uint32_t dst_color_space,int transform)599 static int runcFimcCore(struct hwc_context_t *ctx,
600                         sec_img *src_img,
601                         sec_rect *src_rect,
602                         uint32_t src_color_space,
603                         unsigned int dst_phys_addr,
604                         sec_img *dst_img,
605                         sec_rect *dst_rect,
606                         uint32_t dst_color_space,
607                         int transform)
608 {
609     s5p_fimc_t        * fimc = &ctx->fimc;
610     s5p_fimc_params_t * params = &(fimc->params);
611 
612     unsigned int    frame_size = 0;
613     struct fimc_buf fimc_src_buf;
614 
615     int src_bpp, src_planes;
616     int flag_h_flip = 0;
617     int flag_v_flip = 0;
618     int rotate_value = rotateValueHAL2PP(transform, &flag_h_flip, &flag_v_flip);
619 
620     /* set post processor configuration */
621     params->src.full_width  = src_img->w;
622     params->src.full_height = src_img->h;
623     params->src.start_x     = src_rect->x;
624     params->src.start_y     = src_rect->y;
625     params->src.width       = widthOfPP(fimc->hw_ver, src_color_space, src_rect->w);
626     params->src.height      = heightOfPP(src_color_space, src_rect->h);
627     params->src.color_space = src_color_space;
628 
629 
630     /* check minimum */
631     if (src_rect->w < 16 || src_rect->h < 8) {
632         ALOGE("%s src size is not supported by fimc : f_w=%d f_h=%d x=%d y=%d \
633             	w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
634 				params->src.full_width, params->src.full_height,
635 				params->src.start_x, params->src.start_y, params->src.width,
636 				params->src.height, src_rect->w, src_rect->h,
637 				params->src.color_space);
638         return -1;
639     }
640 
641 switch (rotate_value) {
642     case 0:
643         params->dst.full_width  = dst_img->w;
644         params->dst.full_height = dst_img->h;
645 
646         params->dst.start_x     = dst_rect->x;
647         params->dst.start_y     = dst_rect->y;
648 
649         params->dst.width       =
650             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
651         params->dst.height      = heightOfPP(dst_color_space, dst_rect->h);
652         break;
653     case 90:
654         params->dst.full_width  = dst_img->h;
655         params->dst.full_height = dst_img->w;
656 
657         params->dst.start_x     = dst_rect->y;
658         params->dst.start_y     = dst_img->w - (dst_rect->x + dst_rect->w);
659 
660         params->dst.width       =
661             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
662         params->dst.height      =
663             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
664 
665         if (0x50 > fimc->hw_ver)
666             params->dst.start_y += (dst_rect->w - params->dst.height);
667         break;
668     case 180:
669         params->dst.full_width  = dst_img->w;
670         params->dst.full_height = dst_img->h;
671 
672         params->dst.start_x     = dst_img->w - (dst_rect->x + dst_rect->w);
673         params->dst.start_y     = dst_img->h - (dst_rect->y + dst_rect->h);
674 
675         params->dst.width       =
676             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
677         params->dst.height      = heightOfPP(dst_color_space, dst_rect->h);
678         break;
679     case 270:
680         params->dst.full_width  = dst_img->h;
681         params->dst.full_height = dst_img->w;
682 
683         params->dst.start_x     = dst_img->h - (dst_rect->y + dst_rect->h);
684         params->dst.start_y     = dst_rect->x;
685 
686         params->dst.width       =
687             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
688         params->dst.height      =
689             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
690 
691         if (0x50 > fimc->hw_ver)
692             params->dst.start_y += (dst_rect->w - params->dst.height);
693         break;
694     }
695 
696 
697     params->dst.color_space = dst_color_space;
698 
699     /* check minimum */
700     if (dst_rect->w  < 8 || dst_rect->h < 4) {
701         ALOGE("%s dst size is not supported by fimc : \
702 				f_w=%d f_h=%d x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x",
703 				__func__, params->dst.full_width, params->dst.full_height,
704 				params->dst.start_x, params->dst.start_y, params->dst.width,
705 				params->dst.height, dst_rect->w, dst_rect->h,
706 				params->dst.color_space);
707         return -1;
708     }
709 
710     /* check scaling limit
711      * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
712      */
713     if (((src_rect->w > dst_rect->w) &&
714         ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
715         ((dst_rect->w > src_rect->w) &&
716         ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
717         ALOGE("%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
718             	__func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
719         return -1;
720     }
721 
722 
723     /* set configuration related to destination (DMA-OUT)
724      *   - set input format & size
725      *   - crop input size
726      *   - set input buffer
727      *   - set buffer type (V4L2_MEMORY_USERPTR)
728      */
729     if (fimc_v4l2_set_dst(fimc->dev_fd,
730                           &params->dst,
731                           rotate_value,
732                           flag_h_flip,
733                           flag_v_flip,
734                           dst_phys_addr) < 0) {
735         return -1;
736     }
737 
738     /* set configuration related to source (DMA-INPUT)
739      *   - set input format & size
740      *   - crop input size
741      *   - set input buffer
742      *   - set buffer type (V4L2_MEMORY_USERPTR)
743      */
744     if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0)
745         return -1;
746 
747     /* set input dma address (Y/RGB, Cb, Cr) */
748     switch (src_img->format) {
749     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
750         /* for video display zero copy case */
751         fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
752         fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
753         break;
754 
755     default:
756         /* set source image */
757         fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
758         break;
759     }
760 
761     if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf) < 0) {
762         fimc_v4l2_clr_buf(fimc->dev_fd);
763         return -1;
764     }
765 
766     return 0;
767 }
768 
createFimc(s5p_fimc_t * fimc)769 int createFimc(s5p_fimc_t *fimc)
770 {
771     struct v4l2_capability cap;
772     struct v4l2_format fmt;
773     struct v4l2_control vc;
774 
775     #define  PP_DEVICE_DEV_NAME  "/dev/video1"
776 
777     /* open device file */
778     if(fimc->dev_fd < 0) {
779         fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
780 
781         if (fimc->dev_fd < 0) {
782             ALOGE("%s::Post processor open error (%d)", __func__, errno);
783             goto err;
784         }
785     }
786 
787     /* check capability */
788     if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
789         ALOGE("VIDIOC_QUERYCAP failed");
790         goto err;
791     }
792 
793     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
794         ALOGE("%d has no streaming support", fimc->dev_fd);
795         goto err;
796     }
797 
798     if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
799         ALOGE("%d is no video output", fimc->dev_fd);
800         goto err;
801     }
802 
803     /*
804      * malloc fimc_outinfo structure
805      */
806     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
807     if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
808         ALOGE("%s::Error in video VIDIOC_G_FMT", __func__);
809         goto err;
810     }
811 
812     vc.id = V4L2_CID_FIMC_VERSION;
813     vc.value = 0;
814 
815     if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
816         ALOGE("%s::Error in video VIDIOC_G_CTRL", __func__);
817         goto err;
818     }
819     fimc->hw_ver = vc.value;
820 
821     return 0;
822 
823 err:
824     if (0 <= fimc->dev_fd)
825         close(fimc->dev_fd);
826     fimc->dev_fd = -1;
827 
828     return -1;
829 }
830 
destroyFimc(s5p_fimc_t * fimc)831 int destroyFimc(s5p_fimc_t *fimc)
832 {
833     if (fimc->out_buf.virt_addr != NULL) {
834         fimc->out_buf.virt_addr = NULL;
835         fimc->out_buf.length = 0;
836     }
837 
838     /* close */
839     if (0 <= fimc->dev_fd)
840         close(fimc->dev_fd);
841     fimc->dev_fd = -1;
842 
843     return 0;
844 }
845 
runFimc(struct hwc_context_t * ctx,struct sec_img * src_img,struct sec_rect * src_rect,struct sec_img * dst_img,struct sec_rect * dst_rect,unsigned int * phyAddr,uint32_t transform)846 int runFimc(struct hwc_context_t *ctx,
847             struct sec_img *src_img,
848             struct sec_rect *src_rect,
849             struct sec_img *dst_img,
850             struct sec_rect *dst_rect,
851             unsigned int *phyAddr,
852             uint32_t transform)
853 {
854     s5p_fimc_t *fimc = &ctx->fimc;
855     unsigned int dst_phys_addr = 0;
856     int32_t      src_color_space;
857     int32_t      dst_color_space;
858 
859     /* 1 : source address and size */
860 
861     if(0 > get_src_phys_addr(ctx, src_img, phyAddr))
862         return -1;
863 
864     /* 2 : destination address and size */
865     if(0 == (dst_phys_addr = get_dst_phys_addr(ctx, dst_img)))
866         return -2;
867 
868     /* check whether fimc supports the src format */
869     if (0 > (src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format)))
870         return -3;
871 
872    if (0 > (dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format)))
873         return -4;
874 
875    if(runcFimcCore(ctx, src_img, src_rect, (uint32_t)src_color_space,
876          dst_phys_addr, dst_img, dst_rect, (uint32_t)dst_color_space, transform) < 0)
877         return -5;
878 
879     return 0;
880 }
881