static int prev2resz_ioc_run_engine(struct prev2resz_fhdl *fh) { struct isp_freq_devider *fdiv; int rval; rval = isppreview_s_pipeline(fh->isp_prev, &fh->prev); if (rval != 0) return rval; rval = isppreview_set_inaddr(fh->isp_prev, fh->src_buff_addr); if (rval != 0) return rval; rval = isppreview_config_inlineoffset(fh->isp_prev, fh->prev.in.image.bytesperline); if (rval != 0) return rval; rval = isppreview_set_outaddr(fh->isp_prev, fh->dst_buff_addr); if (rval != 0) return rval; rval = isppreview_config_features(fh->isp_prev, &fh->isp_prev->params); if (rval != 0) return rval; isppreview_set_size(fh->isp_prev, fh->prev.in.image.width, fh->prev.in.image.height); /* Set resizer input and output size */ rval = ispresizer_s_pipeline(fh->isp_resz, &fh->resz); if (rval != 0) return rval; rval = ispresizer_set_outaddr(fh->isp_resz, fh->dst_buff_addr); if (rval != 0) return rval; isp_configure_interface(fh->isp, &p2r_interface); /* * Through-put requirement: * Set max OCP freq for 3630 is 200 MHz through-put * is in KByte/s so 200000 KHz * 4 = 800000 KByte/s */ omap_pm_set_min_bus_tput(fh->isp, OCP_INITIATOR_AGENT, 800000); /* Reduces memory bandwidth */ fdiv = isp_get_upscale_ratio(fh->pipe.in.image.width, fh->pipe.in.image.height, fh->pipe.out.image.width, fh->pipe.out.image.height); dev_dbg(p2r_device, "Set the REQ_EXP register = %d.\n", fdiv->prev_exp); isp_reg_and_or(fh->isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP, ~(ISPSBL_SDR_REQ_PRV_EXP_MASK | ISPSBL_SDR_REQ_RSZ_EXP_MASK), fdiv->prev_exp << ISPSBL_SDR_REQ_PRV_EXP_SHIFT); isp_start(fh->isp); init_completion(&p2r_ctx.resz_complete); rval = isp_set_callback(fh->isp, CBK_RESZ_DONE, prev2resz_resz_callback, (void *) NULL, (void *) NULL); if (rval) { dev_err(p2r_device, "%s: setting resizer callback failed\n", __func__); return rval; } ispresizer_enable(fh->isp_resz, 1); isppreview_enable(fh->isp_prev, 1); rval = wait_for_completion_interruptible_timeout( &p2r_ctx.resz_complete, msecs_to_jiffies(1000)); if (rval == 0) dev_crit(p2r_device, "Resizer interrupt timeout exit\n"); isp_unset_callback(fh->isp, CBK_RESZ_DONE); /* Reset Through-put requirement */ omap_pm_set_min_bus_tput(fh->isp, OCP_INITIATOR_AGENT, -1); /* This will flushes the queue */ if (&fh->src_vbq) videobuf_queue_cancel(&fh->src_vbq); if (&fh->dst_vbq) videobuf_queue_cancel(&fh->dst_vbq); return 0; }
/** ispdss_begin - Function to be called by DSS when resizing of the input * image buffer is needed * @slot: buffer index where the input image is stored * @output_buffer_index: output buffer index where output of resizer will * be stored * @out_off: The line size in bytes for output buffer. as most probably * this will be VRFB with YUV422 data, it should come 0x2000 as input * @out_phy_add: physical address of the start of output memory area for this * @in_phy_add: physical address of the start of input memory area for this * @in_off:: The line size in bytes for output buffer. * ispdss_begin() takes the input buffer index and output buffer index * to start the process of resizing. after resizing is complete, * the callback function will be called with the argument. * Indexes of the input and output buffers are used so that it is faster * and easier to configure the input and output address for the ISP resizer. * As per the current implementation, DSS uses six VRFB contexts for rotation. * for both input and output buffers index and physical address has been taken * as argument. if this buffer is not already mapped to ISP address space we * use physical address to map it, otherwise only the index is used. **/ int ispdss_begin(struct isp_node *pipe, u32 input_buffer_index, int output_buffer_index, u32 out_off, u32 out_phy_add, u32 in_phy_add, u32 in_off) { unsigned int output_size; struct isp_device *isp = dev_get_drvdata(dev_ctx.isp); struct isp_res_device *isp_res = &isp->isp_res; //LGE_CHANGE_S [[email protected]] 2011_04_22, for improve ISP to get 30fps (OMAPS00236923) u32 speed_val = 0; //LGE_CHANGE_E [[email protected]] 2011_04_22, for improve ISP to get 30fps (OMAPS00236923) //LGE_CHANGE_S [[email protected]] 2011_07_19 Froyo_to_GB struct device *dev = to_device(isp_res); //LGE_CHANGE_E [[email protected]] 2011_07_19 Froyo_to_GB if (output_buffer_index >= dev_ctx.num_video_buffers) { dev_err(dev_ctx.isp, "ouput buffer index is out of range %d", output_buffer_index); return -EINVAL; } if (dev_ctx.config_state != STATE_CONFIGURED) { dev_err(dev_ctx.isp, "State not configured \n"); return -EINVAL; } dev_ctx.tmp_buf_size = PAGE_ALIGN(pipe->out.image.bytesperline * pipe->out.image.height); ispdss_tmp_buf_alloc(dev_ctx.tmp_buf_size); pipe->in.path = RSZ_MEM_YUV; if (ispresizer_s_pipeline(isp_res, pipe) != 0) return -EINVAL; /* If this output buffer has not been mapped till now then map it */ if (!dev_ctx.out_buf_virt_addr[output_buffer_index]) { output_size = pipe->out.image.height * out_off; dev_ctx.out_buf_virt_addr[output_buffer_index] = iommu_kmap(isp->iommu, 0, out_phy_add, output_size, IOMMU_FLAG); if (IS_ERR_VALUE( dev_ctx.out_buf_virt_addr[output_buffer_index])) { dev_err(dev_ctx.isp, "Mapping of output buffer failed" "for index \n"); return -ENOMEM; } } if (!dev_ctx.in_buf_virt_addr[input_buffer_index]) { dev_ctx.in_buf_virt_addr[input_buffer_index] = iommu_kmap(isp->iommu, 0, in_phy_add, in_off, IOMMU_FLAG); if (IS_ERR_VALUE( dev_ctx.in_buf_virt_addr[input_buffer_index])) { dev_err(dev_ctx.isp, "Mapping of input buffer failed" "for index \n"); return -ENOMEM; } } if (ispresizer_set_inaddr(isp_res, dev_ctx.in_buf_virt_addr[input_buffer_index], pipe) != 0) return -EINVAL; if (ispresizer_set_out_offset(isp_res, out_off) != 0) return -EINVAL; if (ispresizer_set_outaddr(isp_res, (u32)dev_ctx.out_buf_virt_addr[output_buffer_index]) != 0) return -EINVAL; /* Set ISP callback for the resizing complete even */ if (isp_set_callback(dev_ctx.isp, CBK_RESZ_DONE, ispdss_isr, (void *) NULL, (void *)NULL)) { dev_err(dev_ctx.isp, "No callback for RSZR\n"); return -1; } /* All settings are done.Enable the resizer */ init_completion(&dev_ctx.compl_isr); //LGE_CHANGE_S [[email protected]] 2011_04_22, for improve ISP to get 30fps (OMAPS00236923) // isp_start(dev_ctx.isp); /* Only for 720p case*/ if (use_isp_resizer_decoder){ /*decoder */ speed_val = 0; }else{ /* encoder */ speed_val = 8; } //LGE_CHANGE_S [[email protected]] 2011_07_19 Froyo_to_GB isp_reg_and_or(dev, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP, ~ISPSBL_SDR_REQ_RSZ_EXP_MASK, speed_val << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT); isp_start(dev_ctx.isp); //LGE_CHANGE_E [[email protected]] 2011_07_19 Froyo_to_GB ispresizer_enable(isp_res, 1); /* Wait for resizing complete event */ if (wait_for_completion_interruptible_timeout( &dev_ctx.compl_isr, msecs_to_jiffies(500)) == 0) dev_crit(dev_ctx.isp, "\nTimeout exit from " "wait_for_completion\n"); /* Unset the ISP callback function */ isp_unset_callback(dev_ctx.isp, CBK_RESZ_DONE); return 0; }