예제 #1
0
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;
}
예제 #2
0
파일: ispdss.c 프로젝트: kapoloclubs/diana
/** 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;
}