Logo Search packages:      
Sourcecode: linux-fsl-imx51 version File versions  Download package

static int init_PP ( ipu_channel_params_t params,
vout_data *  vout,
struct device *  dev,
struct fb_info *  fbi,
u16  out_width,
u16  out_height 
) [static]

Initialize PP path

Parameters:
params structure ipu_channel_params_t
vout structure vout_data *
Returns:
status 0 Success

Definition at line 864 of file mxc_v4l2_output.c.

References ipu_channel_params_t::in_height, ipu_channel_params_t::in_pixel_fmt, ipu_channel_params_t::in_width, ipu_channel_params_t::mem_pp_mem, mxc_allocate_buffers(), mxc_free_buffers(), ipu_channel_params_t::out_height, ipu_channel_params_t::out_pixel_fmt, ipu_channel_params_t::out_resize_ratio, and ipu_channel_params_t::out_width.

Referenced by mxc_v4l2out_streamon().

{
      u16 in_width, out_stride; /* stride of output channel */
      u32 eba_offset;
      u16 x_pos;
      u16 y_pos;
      eba_offset = 0;
      x_pos = 0;
      y_pos = 0;

      if (vout->display_ch == ADC_SYS2)
            params->mem_pp_mem.out_pixel_fmt = SDC_FG_FB_FORMAT;
      else
            params->mem_pp_mem.out_pixel_fmt = bpp_to_fmt(fbi);

      if (vout->cur_disp_output == 5) {
            x_pos = (vout->crop_current.left / 8) * 8;
            y_pos = vout->crop_current.top;
            eba_offset = (vout->xres*y_pos + x_pos) *
                        bytes_per_pixel(params->mem_pp_mem.out_pixel_fmt);
      }

      vout->bpp = fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt);
      out_stride = vout->xres *
                        bytes_per_pixel(params->mem_pp_mem.out_pixel_fmt);
      in_width = params->mem_pp_mem.in_width = vout->v2f.fmt.pix.width;
      params->mem_pp_mem.in_height = vout->v2f.fmt.pix.height;
      params->mem_pp_mem.in_pixel_fmt = vout->v2f.fmt.pix.pixelformat;
      params->mem_pp_mem.out_width = out_width;
      params->mem_pp_mem.out_height = out_height;
      params->mem_pp_mem.out_resize_ratio = 0; /* 0 means unused */

      /* split IC by two stripes, the by pass is impossible*/
      if (vout->pp_split) {
            ipu_calc_stripes_sizes(
                              params->mem_pp_mem.in_width, /* input frame width;>1 */
                              params->mem_pp_mem.out_width, /* output frame width; >1 */
                              ipu_ic_out_max_width_size,
                              (((unsigned long long)1) << 32), /* 32bit for fractional*/
                              1,    /* equal stripes */
                              params->mem_pp_mem.in_pixel_fmt,
                              params->mem_pp_mem.out_pixel_fmt,
                              &(vout->pp_left_stripe),
                              &(vout->pp_right_stripe));

            vout->pp_left_stripe.input_column = vout->pp_left_stripe.input_column *
                                                fmt_to_bpp(vout->v2f.fmt.pix.pixelformat) / 8;
            vout->pp_left_stripe.output_column = vout->pp_left_stripe.output_column *
                                                fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt) / 8;
            vout->pp_right_stripe.input_column = vout->pp_right_stripe.input_column *
                                                fmt_to_bpp(vout->v2f.fmt.pix.pixelformat) / 8;
            vout->pp_right_stripe.output_column = vout->pp_right_stripe.output_column *
                                                fmt_to_bpp(params->mem_pp_mem.out_pixel_fmt) / 8;

            /* updare parameters */
            params->mem_pp_mem.in_width = vout->pp_left_stripe.input_width;
            params->mem_pp_mem.out_width = vout->pp_left_stripe.output_width;
            out_width = vout->pp_left_stripe.output_width;
            /* for using in ic_init*/
            params->mem_pp_mem.out_resize_ratio = vout->pp_left_stripe.irr;

            vout->pp_split_buf_num = 0;
      }

      if (ipu_init_channel(vout->post_proc_ch, params) != 0) {
            dev_err(dev, "Error initializing PP channel\n");
            return -EINVAL;
      }

      if (ipu_init_channel_buffer(vout->post_proc_ch,
                            IPU_INPUT_BUFFER,
                            params->mem_pp_mem.in_pixel_fmt,
                            params->mem_pp_mem.in_width,
                            params->mem_pp_mem.in_height,
                            vout->v2f.fmt.pix.bytesperline /
                            bytes_per_pixel(params->mem_pp_mem.
                                  in_pixel_fmt),
                            IPU_ROTATE_NONE,
                            vout->v4l2_bufs[vout->ipu_buf[0]].m.offset,
                            vout->v4l2_bufs[vout->ipu_buf[1]].m.offset,
                            vout->offset.u_offset,
                            vout->offset.v_offset) != 0) {
            dev_err(dev, "Error initializing PP input buffer\n");
            return -EINVAL;
      }

      if (!ipu_can_rotate_in_place(vout->rotate)) {
            if (vout->rot_pp_bufs[0]) {
                  mxc_free_buffers(vout->rot_pp_bufs,
                               vout->rot_pp_bufs_vaddr, 2,
                               vout->display_buf_size);
            }
            if (mxc_allocate_buffers
                (vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2,
                 vout->display_buf_size) < 0) {
                  return -ENOBUFS;
            }

            if (ipu_init_channel_buffer(vout->post_proc_ch,
                                  IPU_OUTPUT_BUFFER,
                                  params->mem_pp_mem.
                                  out_pixel_fmt, out_width,
                                  out_height, out_stride,
                                  IPU_ROTATE_NONE,
                                  vout->rot_pp_bufs[0] + eba_offset,
                                  vout->rot_pp_bufs[1] + eba_offset, 0, 0) != 0) {
                  dev_err(dev, "Error initializing PP output buffer\n");
                  return -EINVAL;
            }

            if (ipu_init_channel(MEM_ROT_PP_MEM, NULL) != 0) {
                  dev_err(dev, "Error initializing PP ROT channel\n");
                  return -EINVAL;
            }
            if (ipu_init_channel_buffer(MEM_ROT_PP_MEM,
                                  IPU_INPUT_BUFFER,
                                  params->mem_pp_mem.
                                  out_pixel_fmt, out_width,
                                  out_height, out_stride,
                                  vout->rotate,
                                  vout->rot_pp_bufs[0],
                                  vout->rot_pp_bufs[1], 0, 0) != 0) {
                  dev_err(dev,
                        "Error initializing PP ROT input buffer\n");
                  return -EINVAL;
            }

            /* swap width and height */
            if (vout->rotate >= IPU_ROTATE_90_RIGHT) {
                  out_width = vout->crop_current.width;
                  out_height = vout->crop_current.height;
            }

            if (ipu_init_channel_buffer(MEM_ROT_PP_MEM,
                                  IPU_OUTPUT_BUFFER,
                                  params->mem_pp_mem.
                                  out_pixel_fmt, out_width,
                                  out_height, out_stride,
                                  IPU_ROTATE_NONE,
                                  vout->display_bufs[0] + eba_offset,
                                  vout->display_bufs[1] + eba_offset, 0, 0) != 0) {
                  dev_err(dev, "Error initializing PP output buffer\n");
                  return -EINVAL;
            }

            if (ipu_link_channels(vout->post_proc_ch, MEM_ROT_PP_MEM) < 0)
                  return -EINVAL;

            vout->display_input_ch = MEM_ROT_PP_MEM;
            ipu_enable_channel(MEM_ROT_PP_MEM);
            ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 0);
            ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 1);
      } else {
            if (ipu_init_channel_buffer(vout->post_proc_ch,
                                  IPU_OUTPUT_BUFFER,
                                  params->mem_pp_mem.
                                  out_pixel_fmt, out_width,
                                  out_height, out_stride,
                                  vout->rotate,
                                  vout->display_bufs[0] + eba_offset,
                                  vout->display_bufs[1] + eba_offset, 0, 0) != 0) {
                  dev_err(dev, "Error initializing PP output buffer\n");
                  return -EINVAL;
            }
      }

      /* fix EBAs for IDMAC channels */
      if (vout->pp_split) {
            ipu_update_channel_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
                                                      0,
                                                      vout->v4l2_bufs[vout->ipu_buf[0]].m.offset +
                                                      vout->pp_left_stripe.input_column);
            ipu_update_channel_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER,
                                                      1,
                                                      vout->v4l2_bufs[vout->ipu_buf[0]].m.offset +
                                                      vout->pp_right_stripe.input_column);
            ipu_update_channel_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER,
                                                      0,
                                                      vout->display_bufs[0] + eba_offset +
                                                      vout->pp_left_stripe.output_column);

            ipu_update_channel_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER,
                                                      1,
                                                      vout->display_bufs[0] + eba_offset +
                                                      vout->pp_right_stripe.output_column);
      }

      return 0;
}


Generated by  Doxygen 1.6.0   Back to index