Home | History | Annotate | Download | only in libhwcomposer
      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 (at) samsung.com)
     20            Sangwoo, Park(sw5771.park (at) samsung.com)
     21            Jamie Oh (jung-min.oh (at) samsung.com)
     22  * @date   2011-07-28
     23  *
     24  */
     25 
     26 #include "SecHWCUtils.h"
     27 
     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         LOGE("%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 		LOGE("%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 
     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 
     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         LOGE("%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         LOGE("%s::S3CFB_WIN_POSITION(%d, %d) fail",
    106             	__func__, window.x, window.y);
    107       return -1;
    108     }
    109 
    110     return 0;
    111 }
    112 
    113 int window_get_info(struct hwc_win_info_t *win)
    114 {
    115     if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
    116         LOGE("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 
    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         LOGE("%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 
    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             LOGE("%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 
    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             LOGE("%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 
    169 int window_get_global_lcd_info(struct fb_var_screeninfo *lcd_info)
    170 {
    171     struct hwc_win_info_t win;
    172     int ret = 0;
    173 
    174     if (window_open(&win, 2)  < 0) {
    175         LOGE("%s:: Failed to open window 2 device ", __func__);
    176         return -1;
    177     }
    178 
    179     if (ioctl(win.fd, FBIOGET_VSCREENINFO, lcd_info) < 0) {
    180         LOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
    181         ret = -1;
    182         goto fun_err;
    183     }
    184 
    185     if (lcd_info->xres == 0) {
    186         lcd_info->xres = DEFAULT_LCD_WIDTH;
    187         lcd_info->xres_virtual = DEFAULT_LCD_WIDTH;
    188     }
    189 
    190     if (lcd_info->yres == 0) {
    191         lcd_info->yres = DEFAULT_LCD_HEIGHT;
    192         lcd_info->yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
    193     }
    194 
    195     if (lcd_info->bits_per_pixel == 0)
    196         lcd_info->bits_per_pixel = DEFAULT_LCD_BPP;
    197 
    198 fun_err:
    199     if (window_close(&win) < 0)
    200         LOGE("%s::window2 close fail", __func__);
    201 
    202     return ret;
    203 }
    204 
    205 int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
    206 {
    207     struct v4l2_format  fmt;
    208     struct v4l2_cropcap cropcap;
    209     struct v4l2_crop    crop;
    210     struct v4l2_requestbuffers req;
    211 
    212     /*
    213      * To set size & format for source image (DMA-INPUT)
    214      */
    215     fmt.type                = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    216     fmt.fmt.pix.width       = src->full_width;
    217     fmt.fmt.pix.height      = src->full_height;
    218     fmt.fmt.pix.pixelformat = src->color_space;
    219     fmt.fmt.pix.field       = V4L2_FIELD_NONE;
    220 
    221     if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) {
    222         LOGE("VIDIOC_S_FMT failed : errno=%d (%s) : fd=%d", errno,
    223                 strerror(errno), fd);
    224         return -1;
    225     }
    226 
    227     /*
    228      * crop input size
    229      */
    230     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    231     if (0x50 == hw_ver) {
    232         crop.c.left   = src->start_x;
    233         crop.c.top    = src->start_y;
    234     } else {
    235         crop.c.left   = 0;
    236         crop.c.top    = 0;
    237     }
    238     crop.c.width  = src->width;
    239     crop.c.height = src->height;
    240     if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
    241         LOGE("Error in video VIDIOC_S_CROP (%d, %d, %d, %d)",
    242                 crop.c.left, crop.c.top, crop.c.width, crop.c.height);
    243         return -1;
    244     }
    245 
    246     /*
    247      * input buffer type
    248      */
    249     req.count       = 1;
    250     req.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    251     req.memory      = V4L2_MEMORY_USERPTR;
    252 
    253     if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
    254         LOGE("Error in VIDIOC_REQBUFS");
    255         return -1;
    256     }
    257 
    258     return 0;
    259 }
    260 
    261 int fimc_v4l2_set_dst(int fd,
    262                       s5p_fimc_img_info *dst,
    263                       int rotation,
    264                       int flag_h_flip,
    265                       int flag_v_flip,
    266                       unsigned int addr)
    267 {
    268     struct v4l2_format      sFormat;
    269     struct v4l2_control     vc;
    270     struct v4l2_framebuffer fbuf;
    271 
    272     /*
    273      * set rotation configuration
    274      */
    275     vc.id = V4L2_CID_HFLIP;
    276     vc.value = flag_h_flip;
    277     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
    278         LOGE("Error in video VIDIOC_S_CTRL - flag_h_flip (%d)", flag_h_flip);
    279         return -1;
    280     }
    281 
    282     vc.id = V4L2_CID_VFLIP;
    283     vc.value = flag_v_flip;
    284     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
    285         LOGE("Error in video VIDIOC_S_CTRL - flag_v_flip (%d)", flag_v_flip);
    286         return -1;
    287     }
    288 
    289     vc.id = V4L2_CID_ROTATION;
    290     vc.value = rotation;
    291     if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
    292         LOGE("Error in video VIDIOC_S_CTRL - rotation (%d)", rotation);
    293         return -1;
    294     }
    295 
    296     /*
    297      * set size, format & address for destination image (DMA-OUTPUT)
    298      */
    299     if (ioctl (fd, VIDIOC_G_FBUF, &fbuf) < 0) {
    300         LOGE("Error in video VIDIOC_G_FBUF");
    301         return -1;
    302     }
    303 
    304     fbuf.base            = (void *)addr;
    305     fbuf.fmt.width       = dst->full_width;
    306     fbuf.fmt.height      = dst->full_height;
    307     fbuf.fmt.pixelformat = dst->color_space;
    308     if (ioctl (fd, VIDIOC_S_FBUF, &fbuf) < 0) {
    309         LOGE("Error in video VIDIOC_S_FBUF 0x%x %d %d %d",
    310                 (void *)addr, dst->full_width, dst->full_height,
    311                 dst->color_space);
    312         return -1;
    313     }
    314 
    315     /*
    316      * set destination window
    317      */
    318     sFormat.type             = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    319     sFormat.fmt.win.w.left   = dst->start_x;
    320     sFormat.fmt.win.w.top    = dst->start_y;
    321     sFormat.fmt.win.w.width  = dst->width;
    322     sFormat.fmt.win.w.height = dst->height;
    323     if (ioctl(fd, VIDIOC_S_FMT, &sFormat) < 0) {
    324         LOGE("Error in video VIDIOC_S_FMT %d %d %d %d",
    325                 dst->start_x, dst->start_y, dst->width, dst->height);
    326         return -1;
    327     }
    328 
    329     return 0;
    330 }
    331 
    332 int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
    333 {
    334     if (ioctl (fd, VIDIOC_STREAMON, &type) < 0) {
    335         LOGE("Error in VIDIOC_STREAMON");
    336         return -1;
    337     }
    338 
    339     return 0;
    340 }
    341 
    342 int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf)
    343 {
    344     struct v4l2_buffer buf;
    345 
    346     buf.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    347     buf.memory      = V4L2_MEMORY_USERPTR;
    348     buf.m.userptr   = (unsigned long)fimc_buf;
    349     buf.length      = 0;
    350     buf.index       = 0;
    351 
    352     if (ioctl (fd, VIDIOC_QBUF, &buf) < 0) {
    353         LOGE("Error in VIDIOC_QBUF");
    354         return -1;
    355     }
    356 
    357     return 0;
    358 }
    359 
    360 int fimc_v4l2_dequeue(int fd)
    361 {
    362     struct v4l2_buffer buf;
    363 
    364     buf.type        = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    365     buf.memory      = V4L2_MEMORY_USERPTR;
    366 
    367     if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) {
    368         LOGE("Error in VIDIOC_DQBUF");
    369         return -1;
    370     }
    371 
    372     return buf.index;
    373 }
    374 
    375 int fimc_v4l2_stream_off(int fd)
    376 {
    377     enum v4l2_buf_type type;
    378     type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    379 
    380     if (ioctl (fd, VIDIOC_STREAMOFF, &type) < 0) {
    381         LOGE("Error in VIDIOC_STREAMOFF");
    382         return -1;
    383     }
    384 
    385     return 0;
    386 }
    387 
    388 int fimc_v4l2_clr_buf(int fd)
    389 {
    390     struct v4l2_requestbuffers req;
    391 
    392     req.count   = 0;
    393     req.type    = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    394     req.memory  = V4L2_MEMORY_USERPTR;
    395 
    396     if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
    397         LOGE("Error in VIDIOC_REQBUFS");
    398     }
    399 
    400     return 0;
    401 }
    402 
    403 int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf)
    404 {
    405     int ret =0;
    406 
    407     if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT) < 0) {
    408         LOGE("Fail : v4l2_stream_on()");
    409         return -1;
    410     }
    411 
    412     if (fimc_v4l2_queue(fd, fimc_buf) < 0) {
    413         LOGE("Fail : v4l2_queue()");
    414         ret = -1;
    415         goto stream_off;
    416     }
    417 
    418     if (fimc_v4l2_dequeue(fd) < 0) {
    419         LOGE("Fail : v4l2_dequeue()");
    420         ret = -1;
    421         goto stream_off;
    422     }
    423 
    424 stream_off:
    425     if (fimc_v4l2_stream_off(fd) < 0) {
    426         LOGE("Fail : v4l2_stream_off()");
    427         return -1;
    428     }
    429 
    430     if (fimc_v4l2_clr_buf(fd) < 0) {
    431         LOGE("Fail : v4l2_clr_buf()");
    432         return -1;
    433     }
    434 
    435     return ret;
    436 }
    437 
    438 static int get_src_phys_addr(struct hwc_context_t *ctx,
    439                              sec_img *src_img,
    440                              unsigned int *phyAddr)
    441 {
    442     s5p_fimc_t *fimc = &ctx->fimc;
    443 
    444    if(src_img->mem_type == HWC_PHYS_MEM_TYPE) {
    445         switch(src_img->format) {
    446         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    447             fimc->params.src.buf_addr_phy_rgb_y = phyAddr[0];
    448             fimc->params.src.buf_addr_phy_cb    = phyAddr[1];
    449             break;
    450         default:
    451             LOGE("%s format error (format=0x%x)", __func__,
    452                     src_img->format);
    453             return -1;
    454         }
    455     } else {
    456         LOGE("%s mem_type error (mem_type=%d)", __func__, src_img->mem_type);
    457         return -1;
    458     }
    459 
    460     return 0;
    461 }
    462 
    463 static int get_dst_phys_addr(struct hwc_context_t *ctx,
    464                              sec_img *dst_img)
    465 {
    466     unsigned int dst_phys_addr  = 0;
    467 
    468     if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
    469         dst_phys_addr = dst_img->base;
    470     else {
    471         LOGE("%s::get_dst_phys_addr fail ", __func__);
    472         dst_phys_addr = 0;
    473     }
    474     return dst_phys_addr;
    475 }
    476 
    477 static inline int rotateValueHAL2PP(unsigned char transform,
    478                                     int *flag_h_flip,
    479                                     int *flag_v_flip)
    480 {
    481     int rotate_result = 0;
    482     int rotate_flag = transform & 0x7;
    483 
    484     switch (rotate_flag) {
    485     case HAL_TRANSFORM_ROT_90:
    486         rotate_result = 90;
    487         break;
    488     case HAL_TRANSFORM_ROT_180:
    489         rotate_result = 180;
    490         break;
    491     case HAL_TRANSFORM_ROT_270:
    492         rotate_result = 270;
    493         break;
    494     }
    495 
    496     switch (rotate_flag) {
    497     case HAL_TRANSFORM_FLIP_H:
    498         *flag_h_flip = 1;
    499         *flag_v_flip = 0;
    500         break;
    501     case HAL_TRANSFORM_FLIP_V:
    502         *flag_h_flip = 0;
    503         *flag_v_flip = 1;
    504         break;
    505     default:
    506         *flag_h_flip = 0;
    507         *flag_v_flip = 0;
    508         break;
    509     }
    510 
    511     return rotate_result;
    512 }
    513 
    514 static inline int multipleOfN(int number, int N)
    515 {
    516     int result = number;
    517     switch (N) {
    518     case 1:
    519     case 2:
    520     case 4:
    521     case 8:
    522     case 16:
    523     case 32:
    524     case 64:
    525     case 128:
    526     case 256:
    527         result = (number - (number & (N-1)));
    528         break;
    529     default:
    530         result = number - (number % N);
    531         break;
    532     }
    533     return result;
    534 }
    535 
    536 static inline int widthOfPP(unsigned int ver,
    537                             int pp_color_format,
    538                             int number)
    539 {
    540     if (0x50 == ver) {
    541         switch(pp_color_format) {
    542         /* 422 1/2/3 plane */
    543         case V4L2_PIX_FMT_YUYV:
    544         case V4L2_PIX_FMT_UYVY:
    545         case V4L2_PIX_FMT_NV61:
    546         case V4L2_PIX_FMT_NV16:
    547         case V4L2_PIX_FMT_YUV422P:
    548 
    549         /* 420 2/3 plane */
    550         case V4L2_PIX_FMT_NV21:
    551         case V4L2_PIX_FMT_NV12:
    552         case V4L2_PIX_FMT_NV12T:
    553         case V4L2_PIX_FMT_YUV420:
    554             return multipleOfN(number, 2);
    555 
    556         default :
    557             return number;
    558         }
    559     } else {
    560         switch(pp_color_format) {
    561         case V4L2_PIX_FMT_RGB565:
    562             return multipleOfN(number, 8);
    563 
    564         case V4L2_PIX_FMT_RGB32:
    565             return multipleOfN(number, 4);
    566 
    567         case V4L2_PIX_FMT_YUYV:
    568         case V4L2_PIX_FMT_UYVY:
    569             return multipleOfN(number, 4);
    570 
    571         case V4L2_PIX_FMT_NV61:
    572         case V4L2_PIX_FMT_NV16:
    573             return multipleOfN(number, 8);
    574 
    575         case V4L2_PIX_FMT_YUV422P:
    576             return multipleOfN(number, 16);
    577 
    578         case V4L2_PIX_FMT_NV21:
    579         case V4L2_PIX_FMT_NV12:
    580         case V4L2_PIX_FMT_NV12T:
    581             return multipleOfN(number, 8);
    582 
    583         case V4L2_PIX_FMT_YUV420:
    584             return multipleOfN(number, 16);
    585 
    586         default :
    587             return number;
    588         }
    589     }
    590     return number;
    591 }
    592 
    593 static inline int heightOfPP(int pp_color_format,
    594                              int number)
    595 {
    596     switch(pp_color_format) {
    597     case V4L2_PIX_FMT_NV21:
    598     case V4L2_PIX_FMT_NV12:
    599     case V4L2_PIX_FMT_NV12T:
    600     case V4L2_PIX_FMT_YUV420:
    601         return multipleOfN(number, 2);
    602 
    603     default :
    604         return number;
    605     }
    606     return number;
    607 }
    608 
    609 static int runcFimcCore(struct hwc_context_t *ctx,
    610                         sec_img *src_img,
    611                         sec_rect *src_rect,
    612                         uint32_t src_color_space,
    613                         unsigned int dst_phys_addr,
    614                         sec_img *dst_img,
    615                         sec_rect *dst_rect,
    616                         uint32_t dst_color_space,
    617                         int transform)
    618 {
    619     s5p_fimc_t        * fimc = &ctx->fimc;
    620     s5p_fimc_params_t * params = &(fimc->params);
    621 
    622     unsigned int    frame_size = 0;
    623     struct fimc_buf fimc_src_buf;
    624 
    625     int src_bpp, src_planes;
    626     int flag_h_flip = 0;
    627     int flag_v_flip = 0;
    628     int rotate_value = rotateValueHAL2PP(transform, &flag_h_flip, &flag_v_flip);
    629 
    630     /* set post processor configuration */
    631     params->src.full_width  = src_img->w;
    632     params->src.full_height = src_img->h;
    633     params->src.start_x     = src_rect->x;
    634     params->src.start_y     = src_rect->y;
    635     params->src.width       = widthOfPP(fimc->hw_ver, src_color_space, src_rect->w);
    636     params->src.height      = heightOfPP(src_color_space, src_rect->h);
    637     params->src.color_space = src_color_space;
    638 
    639 
    640     /* check minimum */
    641     if (src_rect->w < 16 || src_rect->h < 8) {
    642         LOGE("%s src size is not supported by fimc : f_w=%d f_h=%d x=%d y=%d \
    643             	w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
    644 				params->src.full_width, params->src.full_height,
    645 				params->src.start_x, params->src.start_y, params->src.width,
    646 				params->src.height, src_rect->w, src_rect->h,
    647 				params->src.color_space);
    648         return -1;
    649     }
    650 
    651 switch (rotate_value) {
    652     case 0:
    653         params->dst.full_width  = dst_img->w;
    654         params->dst.full_height = dst_img->h;
    655 
    656         params->dst.start_x     = dst_rect->x;
    657         params->dst.start_y     = dst_rect->y;
    658 
    659         params->dst.width       =
    660             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
    661         params->dst.height      = heightOfPP(dst_color_space, dst_rect->h);
    662         break;
    663     case 90:
    664         params->dst.full_width  = dst_img->h;
    665         params->dst.full_height = dst_img->w;
    666 
    667         params->dst.start_x     = dst_rect->y;
    668         params->dst.start_y     = dst_img->w - (dst_rect->x + dst_rect->w);
    669 
    670         params->dst.width       =
    671             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
    672         params->dst.height      =
    673             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
    674 
    675         if (0x50 > fimc->hw_ver)
    676             params->dst.start_y += (dst_rect->w - params->dst.height);
    677         break;
    678     case 180:
    679         params->dst.full_width  = dst_img->w;
    680         params->dst.full_height = dst_img->h;
    681 
    682         params->dst.start_x     = dst_img->w - (dst_rect->x + dst_rect->w);
    683         params->dst.start_y     = dst_img->h - (dst_rect->y + dst_rect->h);
    684 
    685         params->dst.width       =
    686             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
    687         params->dst.height      = heightOfPP(dst_color_space, dst_rect->h);
    688         break;
    689     case 270:
    690         params->dst.full_width  = dst_img->h;
    691         params->dst.full_height = dst_img->w;
    692 
    693         params->dst.start_x     = dst_img->h - (dst_rect->y + dst_rect->h);
    694         params->dst.start_y     = dst_rect->x;
    695 
    696         params->dst.width       =
    697             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
    698         params->dst.height      =
    699             widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
    700 
    701         if (0x50 > fimc->hw_ver)
    702             params->dst.start_y += (dst_rect->w - params->dst.height);
    703         break;
    704     }
    705 
    706 
    707     params->dst.color_space = dst_color_space;
    708 
    709     /* check minimum */
    710     if (dst_rect->w  < 8 || dst_rect->h < 4) {
    711         LOGE("%s dst size is not supported by fimc : \
    712 				f_w=%d f_h=%d x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x",
    713 				__func__, params->dst.full_width, params->dst.full_height,
    714 				params->dst.start_x, params->dst.start_y, params->dst.width,
    715 				params->dst.height, dst_rect->w, dst_rect->h,
    716 				params->dst.color_space);
    717         return -1;
    718     }
    719 
    720     /* check scaling limit
    721      * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
    722      */
    723     if (((src_rect->w > dst_rect->w) &&
    724         ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
    725         ((dst_rect->w > src_rect->w) &&
    726         ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
    727         LOGE("%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
    728             	__func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
    729         return -1;
    730     }
    731 
    732 
    733     /* set configuration related to destination (DMA-OUT)
    734      *   - set input format & size
    735      *   - crop input size
    736      *   - set input buffer
    737      *   - set buffer type (V4L2_MEMORY_USERPTR)
    738      */
    739     if (fimc_v4l2_set_dst(fimc->dev_fd,
    740                           &params->dst,
    741                           rotate_value,
    742                           flag_h_flip,
    743                           flag_v_flip,
    744                           dst_phys_addr) < 0) {
    745         return -1;
    746     }
    747 
    748     /* set configuration related to source (DMA-INPUT)
    749      *   - set input format & size
    750      *   - crop input size
    751      *   - set input buffer
    752      *   - set buffer type (V4L2_MEMORY_USERPTR)
    753      */
    754     if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0)
    755         return -1;
    756 
    757     /* set input dma address (Y/RGB, Cb, Cr) */
    758     switch (src_img->format) {
    759     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    760         /* for video display zero copy case */
    761         fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
    762         fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
    763         break;
    764 
    765     default:
    766         /* set source image */
    767         fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
    768         break;
    769     }
    770 
    771     if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf) < 0) {
    772         fimc_v4l2_clr_buf(fimc->dev_fd);
    773         return -1;
    774     }
    775 
    776     return 0;
    777 }
    778 
    779 int createFimc(s5p_fimc_t *fimc)
    780 {
    781     struct v4l2_capability cap;
    782     struct v4l2_format fmt;
    783     struct v4l2_control vc;
    784 
    785     #define  PP_DEVICE_DEV_NAME  "/dev/video1"
    786 
    787     /* open device file */
    788     if(fimc->dev_fd < 0) {
    789         fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
    790 
    791         if (fimc->dev_fd < 0) {
    792             LOGE("%s::Post processor open error (%d)", __func__, errno);
    793             goto err;
    794         }
    795     }
    796 
    797     /* check capability */
    798     if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
    799         LOGE("VIDIOC_QUERYCAP failed");
    800         goto err;
    801     }
    802 
    803     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
    804         LOGE("%d has no streaming support", fimc->dev_fd);
    805         goto err;
    806     }
    807 
    808     if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
    809         LOGE("%d is no video output", fimc->dev_fd);
    810         goto err;
    811     }
    812 
    813     /*
    814      * malloc fimc_outinfo structure
    815      */
    816     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    817     if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
    818         LOGE("%s::Error in video VIDIOC_G_FMT", __func__);
    819         goto err;
    820     }
    821 
    822     vc.id = V4L2_CID_FIMC_VERSION;
    823     vc.value = 0;
    824 
    825     if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
    826         LOGE("%s::Error in video VIDIOC_G_CTRL", __func__);
    827         goto err;
    828     }
    829     fimc->hw_ver = vc.value;
    830 
    831     return 0;
    832 
    833 err:
    834     if (0 <= fimc->dev_fd)
    835         close(fimc->dev_fd);
    836     fimc->dev_fd = -1;
    837 
    838     return -1;
    839 }
    840 
    841 int destroyFimc(s5p_fimc_t *fimc)
    842 {
    843     if (fimc->out_buf.virt_addr != NULL) {
    844         fimc->out_buf.virt_addr = NULL;
    845         fimc->out_buf.length = 0;
    846     }
    847 
    848     /* close */
    849     if (0 <= fimc->dev_fd)
    850         close(fimc->dev_fd);
    851     fimc->dev_fd = -1;
    852 
    853     return 0;
    854 }
    855 
    856 int runFimc(struct hwc_context_t *ctx,
    857             struct sec_img *src_img,
    858             struct sec_rect *src_rect,
    859             struct sec_img *dst_img,
    860             struct sec_rect *dst_rect,
    861             unsigned int *phyAddr,
    862             uint32_t transform)
    863 {
    864     s5p_fimc_t *fimc = &ctx->fimc;
    865     unsigned int dst_phys_addr = 0;
    866     int32_t      src_color_space;
    867     int32_t      dst_color_space;
    868 
    869     /* 1 : source address and size */
    870 
    871     if(0 > get_src_phys_addr(ctx, src_img, phyAddr))
    872         return -1;
    873 
    874     /* 2 : destination address and size */
    875     if(0 == (dst_phys_addr = get_dst_phys_addr(ctx, dst_img)))
    876         return -2;
    877 
    878     /* check whether fimc supports the src format */
    879     if (0 > (src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format)))
    880         return -3;
    881 
    882    if (0 > (dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format)))
    883         return -4;
    884 
    885    if(runcFimcCore(ctx, src_img, src_rect, (uint32_t)src_color_space,
    886          dst_phys_addr, dst_img, dst_rect, (uint32_t)dst_color_space, transform) < 0)
    887         return -5;
    888 
    889     return 0;
    890 }
    891