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

static int mxc_pf_start ( pf_buf in,
pf_buf out,
int  qp_buf 
) [static]

This function handles PF_IOCTL_START calls. It sets the PF channel buffers addresses and starts the channels

Returns:
This function returns 0 on success or negative error code on error.

Definition at line 362 of file mxc_pf.c.

References pf_buf::offset, pf_buf::u_offset, pf_buf::v_offset, and pf_buf::y_offset.

Referenced by mxc_pf_ioctl().

{
      int err;
      dma_addr_t y_in_paddr;
      dma_addr_t u_in_paddr;
      dma_addr_t v_in_paddr;
      dma_addr_t p1_in_paddr;
      dma_addr_t p2_in_paddr;
      dma_addr_t y_out_paddr;
      dma_addr_t u_out_paddr;
      dma_addr_t v_out_paddr;

      /* H.264 requires output buffer equal to input */
      if (pf_data.mode == PF_H264_DEBLOCK)
            out = in;

      y_in_paddr = in->offset + in->y_offset;
      if (in->u_offset)
            u_in_paddr = in->offset + in->u_offset;
      else
            u_in_paddr = y_in_paddr + (pf_data.stride * pf_data.height);
      if (in->v_offset)
            v_in_paddr = in->offset + in->v_offset;
      else
            v_in_paddr = u_in_paddr + (pf_data.stride * pf_data.height) / 4;
      p1_in_paddr = pf_data.qp_paddr;
      if (qp_buf)
            p1_in_paddr += pf_data.qp_size / 2;

      if (pf_data.mode == PF_H264_DEBLOCK) {
            p2_in_paddr = p1_in_paddr +
                ((pf_data.width + 15) / 16) *
                ((pf_data.height + 15) / 16) * 4;
      } else {
            p2_in_paddr = 0;
      }

      pr_debug("y_in_paddr = 0x%08X\nu_in_paddr = 0x%08X\n"
             "v_in_paddr = 0x%08X\n"
             "qp_paddr = 0x%08X\nbsb_paddr = 0x%08X\n",
             y_in_paddr, u_in_paddr, v_in_paddr, p1_in_paddr, p2_in_paddr);

      y_out_paddr = out->offset + out->y_offset;
      if (out->u_offset)
            u_out_paddr = out->offset + out->u_offset;
      else
            u_out_paddr = y_out_paddr + (pf_data.stride * pf_data.height);
      if (out->v_offset)
            v_out_paddr = out->offset + out->v_offset;
      else
            v_out_paddr =
                u_out_paddr + (pf_data.stride * pf_data.height) / 4;

      pr_debug("y_out_paddr = 0x%08X\nu_out_paddr = 0x%08X\n"
             "v_out_paddr = 0x%08X\n",
             y_out_paddr, u_out_paddr, v_out_paddr);

      pf_data.done_mask = 0;

      ipu_enable_irq(IPU_IRQ_PF_Y_OUT_EOF);
      if (pf_data.mode != PF_MPEG4_DERING) {
            ipu_enable_irq(IPU_IRQ_PF_U_OUT_EOF);
            ipu_enable_irq(IPU_IRQ_PF_V_OUT_EOF);
      }

      err = ipu_update_channel_buffer(MEM_PF_Y_MEM, IPU_INPUT_BUFFER, 0,
                              y_in_paddr);
      if (err < 0) {
            printk(KERN_ERR "mxc_pf: error setting Y input buffer\n");
            goto err0;
      }

      err = ipu_update_channel_buffer(MEM_PF_Y_MEM, IPU_OUTPUT_BUFFER, 0,
                              y_out_paddr);
      if (err < 0) {
            printk(KERN_ERR "mxc_pf: error setting Y output buffer\n");
            goto err0;
      }

      if (pf_data.mode != PF_MPEG4_DERING) {
            err =
                ipu_update_channel_buffer(MEM_PF_U_MEM, IPU_INPUT_BUFFER, 0,
                                    u_in_paddr);
            if (err < 0) {
                  printk(KERN_ERR
                         "mxc_pf: error setting U input buffer\n");
                  goto err0;
            }

            err =
                ipu_update_channel_buffer(MEM_PF_U_MEM, IPU_OUTPUT_BUFFER,
                                    0, u_out_paddr);
            if (err < 0) {
                  printk(KERN_ERR
                         "mxc_pf: error setting U output buffer\n");
                  goto err0;
            }

            err =
                ipu_update_channel_buffer(MEM_PF_V_MEM, IPU_INPUT_BUFFER, 0,
                                    v_in_paddr);
            if (err < 0) {
                  printk(KERN_ERR
                         "mxc_pf: error setting V input buffer\n");
                  goto err0;
            }

            err =
                ipu_update_channel_buffer(MEM_PF_V_MEM, IPU_OUTPUT_BUFFER,
                                    0, v_out_paddr);
            if (err < 0) {
                  printk(KERN_ERR
                         "mxc_pf: error setting V output buffer\n");
                  goto err0;
            }
      }

      err = ipu_update_channel_buffer(MEM_PF_Y_MEM, IPU_SEC_INPUT_BUFFER, 0,
                              p1_in_paddr);
      if (err < 0) {
            printk(KERN_ERR "mxc_pf: error setting QP buffer\n");
            goto err0;
      }

      if (pf_data.mode == PF_H264_DEBLOCK) {

            err = ipu_update_channel_buffer(MEM_PF_U_MEM,
                                    IPU_SEC_INPUT_BUFFER, 0,
                                    p2_in_paddr);
            if (err < 0) {
                  printk(KERN_ERR
                         "mxc_pf: error setting H264 BSB buffer\n");
                  goto err0;
            }
            ipu_select_buffer(MEM_PF_U_MEM, IPU_SEC_INPUT_BUFFER, 0);
      }

      ipu_select_buffer(MEM_PF_Y_MEM, IPU_OUTPUT_BUFFER, 0);
      ipu_select_buffer(MEM_PF_Y_MEM, IPU_SEC_INPUT_BUFFER, 0);
      ipu_select_buffer(MEM_PF_Y_MEM, IPU_INPUT_BUFFER, 0);
      if (pf_data.mode != PF_MPEG4_DERING) {
            ipu_select_buffer(MEM_PF_U_MEM, IPU_OUTPUT_BUFFER, 0);
            ipu_select_buffer(MEM_PF_V_MEM, IPU_OUTPUT_BUFFER, 0);
            ipu_select_buffer(MEM_PF_U_MEM, IPU_INPUT_BUFFER, 0);
            ipu_select_buffer(MEM_PF_V_MEM, IPU_INPUT_BUFFER, 0);
      }

      if (!pf_data.pf_enabled) {
            pf_data.pf_enabled = 1;
            if (pf_data.mode != PF_MPEG4_DERING) {
                  ipu_enable_channel(MEM_PF_V_MEM);
                  ipu_enable_channel(MEM_PF_U_MEM);
            }
            ipu_enable_channel(MEM_PF_Y_MEM);
      }

      return 0;
      err0:
      return err;
}


Generated by  Doxygen 1.6.0   Back to index