static int msm_csid_config(struct csid_device *csid_dev,
	struct msm_camera_csid_params *csid_params)
{
	int rc = 0;
	uint32_t val = 0, clk_rate = 0, round_rate = 0;
	struct clk **csid_clk_ptr;
	void __iomem *csidbase;
	csidbase = csid_dev->base;
	if (!csidbase || !csid_params) {
		pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
			__LINE__, csidbase, csid_params);
		return -EINVAL;
	}

	CDBG("%s csid_params, lane_cnt = %d, lane_assign = 0x%x\n",
		__func__,
		csid_params->lane_cnt,
		csid_params->lane_assign);
	CDBG("%s csid_params phy_sel = %d\n", __func__,
		csid_params->phy_sel);

	msm_csid_reset(csid_dev);

	csid_clk_ptr = csid_dev->csid_clk;
	if (!csid_clk_ptr) {
		pr_err("csi_src_clk get failed\n");
		return -EINVAL;
	}

	clk_rate = (csid_params->csi_clk > 0) ?
				(csid_params->csi_clk) : csid_dev->csid_max_clk;
	round_rate = clk_round_rate(csid_clk_ptr[csid_dev->csid_clk_index],
					clk_rate);
	if (round_rate > csid_dev->csid_max_clk)
		round_rate = csid_dev->csid_max_clk;
	pr_debug("usr set rate csi_clk clk_rate = %u round_rate = %u\n",
					clk_rate, round_rate);
	rc = clk_set_rate(csid_clk_ptr[csid_dev->csid_clk_index],
				round_rate);
	if (rc < 0) {
		pr_err("csi_src_clk set failed\n");
		return rc;
	}

	val = csid_params->lane_cnt - 1;
	val |= csid_params->lane_assign <<
		csid_dev->ctrl_reg->csid_reg.csid_dl_input_sel_shift;
	if (csid_dev->hw_version < 0x30000000) {
		val |= (0xF << 10);
		msm_camera_io_w(val, csidbase +
		csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_0_addr);
	} else {
		msm_camera_io_w(val, csidbase +
		csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_0_addr);
		val = csid_params->phy_sel <<
			csid_dev->ctrl_reg->csid_reg.csid_phy_sel_shift;
		val |= 0xF;
		msm_camera_io_w(val, csidbase +
		csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_1_addr);
	}

	rc = msm_csid_cid_lut(&csid_params->lut_params, csid_dev);
	if (rc < 0)
		return rc;

	msm_csid_set_debug_reg(csid_dev, csid_params);
	return rc;
}
static int msm_csid_release(struct csid_device *csid_dev)
{
	uint32_t irq;

	if (csid_dev->csid_state != CSID_POWER_UP) {
		pr_err("%s: csid invalid state %d\n", __func__,
			csid_dev->csid_state);
		return -EINVAL;
	}

	CDBG("%s:%d, hw_version = 0x%x\n", __func__, __LINE__,
		csid_dev->hw_version);

	irq = msm_camera_io_r(csid_dev->base +
		csid_dev->ctrl_reg->csid_reg.csid_irq_status_addr);
	msm_camera_io_w(irq, csid_dev->base +
		csid_dev->ctrl_reg->csid_reg.csid_irq_clear_cmd_addr);
	msm_camera_io_w(0, csid_dev->base +
		csid_dev->ctrl_reg->csid_reg.csid_irq_mask_addr);

	disable_irq(csid_dev->irq->start);

	if (csid_dev->hw_version == CSID_VERSION_V20) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
			csid_dev->csid_clk, csid_dev->num_clk, 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else if (csid_dev->hw_version == CSID_VERSION_V22) {
		msm_cam_clk_enable(&csid_dev->pdev->dev,
			csid_clk_info,
			csid_dev->csid_clk,
			csid_dev->num_clk, 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else if ((csid_dev->hw_version >= CSID_VERSION_V30 &&
		csid_dev->hw_version < CSID_VERSION_V31) ||
		(csid_dev->hw_version == CSID_VERSION_V40) ||
		(csid_dev->hw_version == CSID_VERSION_V31_1) ||
		(csid_dev->hw_version == CSID_VERSION_V31_3)) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
			csid_dev->csid_clk, csid_dev->num_clk, 0);
		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else if ((csid_dev->hw_version == CSID_VERSION_V31) ||
		(csid_dev->hw_version == CSID_VERSION_V32) ||
		(csid_dev->hw_version == CSID_VERSION_V33) ||
		(csid_dev->hw_version == CSID_VERSION_V37) ||
		(csid_dev->hw_version == CSID_VERSION_V34)) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
			csid_dev->csid_clk, csid_dev->num_clk, 0);
		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else {
		pr_err("%s:%d, invalid hw version : 0x%x", __func__, __LINE__,
			csid_dev->hw_version);
		return -EINVAL;
	}

	if (!IS_ERR_OR_NULL(csid_dev->reg_ptr)) {
		regulator_disable(csid_dev->reg_ptr);
		regulator_put(csid_dev->reg_ptr);
	}

	iounmap(csid_dev->base);
	csid_dev->base = NULL;
	csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;
}
예제 #3
0
static void msm_cci_flush_queue(struct cci_device *cci_dev,
	enum cci_i2c_master_t master)
{
	int32_t rc = 0;
#if defined(CONFIG_SONY_CAM_QCAMERA)
	uint8_t retry_count = 0;
#endif

	msm_camera_io_w(1 << master, cci_dev->base + CCI_HALT_REQ_ADDR);
#if defined(CONFIG_SONY_CAM_QCAMERA)
	retry_count = 4;
	do {
		rc = wait_for_completion_interruptible_timeout(
			&cci_dev->cci_master_info[master].reset_complete,
			CCI_TIMEOUT);
		retry_count--;
		if (rc != -ERESTARTSYS)
			break;
		pr_debug("%s: wait_event interrupted by signal, count = %d",
				__func__, retry_count);
		msleep(20);
	} while (retry_count > 0);
#else
	rc = wait_for_completion_interruptible_timeout(
		&cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
#endif
	if (rc < 0) {
		pr_err("%s:%d wait failed\n", __func__, __LINE__);
	} else if (rc == 0) {
		pr_err("%s:%d wait timeout\n", __func__, __LINE__);

		/* Set reset pending flag to TRUE */
		cci_dev->cci_master_info[master].reset_pending = TRUE;

		/* Set proper mask to RESET CMD address based on MASTER */
		if (master == MASTER_0)
			msm_camera_io_w(CCI_M0_RESET_RMSK,
				cci_dev->base + CCI_RESET_CMD_ADDR);
		else
			msm_camera_io_w(CCI_M1_RESET_RMSK,
				cci_dev->base + CCI_RESET_CMD_ADDR);

		/* wait for reset done irq */
#if defined(CONFIG_SONY_CAM_QCAMERA)
		retry_count = 4;
		do {
			rc = wait_for_completion_interruptible_timeout(
				&cci_dev->cci_master_info[master].reset_complete
				, CCI_TIMEOUT);
			retry_count--;
			if (rc != -ERESTARTSYS)
				break;
			pr_debug("%s: wait_event interrupted by signal, count = %d",
					__func__, retry_count);
			msleep(20);
		} while (retry_count > 0);
#else
		rc = wait_for_completion_interruptible_timeout(
			&cci_dev->cci_master_info[master].reset_complete,
			CCI_TIMEOUT);
#endif
		if (rc <= 0)
			pr_err("%s:%d wait failed %d\n", __func__, __LINE__,
				rc);
	}
	return;
}
예제 #4
0
static int msm_ispif_reset_hw(struct ispif_device *ispif, int release)
{
	int rc = 0, i;
	long timeout = 0;
	struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)];
	ispif->clk_idx = 0;

	rc = msm_ispif_get_clk_info(ispif, ispif->pdev,
		ispif_ahb_clk_info, ispif_clk_info);
	if (rc < 0) {
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
		return -EFAULT;
	}

	/* Turn ON regulators before enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 1);
	if (rc < 0) {
		pr_err("%s: ispif enable regulator failed", __func__);
			return -EFAULT;
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d\n",
			__func__, rc);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 1);
		if (rc < 0) {
			pr_err("%s: cannot enable clock, error = %d",
				__func__, rc);
		} else {
			/* This is set when device is 8x26 */
			ispif->clk_idx = 2;
		}
	} else {
		/* This is set when device is 8974 */
		ispif->clk_idx = 1;
	}

	if (release) {
		for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
			msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY,
				ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
			msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY,
				ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
		}
		msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD,
			ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
	}
	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->hw_num_isps > 1)
		init_completion(&ispif->reset_complete[VFE1]);

	/* initiate reset of ISPIF */
	msm_camera_io_w(ISPIF_RST_CMD_MASK,
				ispif->base + ISPIF_RST_CMD_ADDR);


	timeout = wait_for_completion_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
	CDBG("%s: VFE0 done\n", __func__);

	if (timeout <= 0) {
		pr_err("%s: VFE0 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			rc = msm_cam_clk_enable(&ispif->pdev->dev,
				ispif_8626_reset_clk_info, reset_clk1,
				ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
			if (rc < 0)
				pr_err("%s: VFE0 reset wait timeout\n",
					__func__);
		}
		/* Turn OFF regulators */
		rc = msm_ispif_set_regulator(ispif, 0);
		return -ETIMEDOUT;
	}

	if (ispif->hw_num_isps > 1) {
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
					ispif->base + ISPIF_RST_CMD_1_ADDR);
		timeout = wait_for_completion_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		CDBG("%s: VFE1 done\n", __func__);
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
			/* Turn OFF regulators */
			rc = msm_ispif_set_regulator(ispif, 0);
			return -ETIMEDOUT;
		}
	}

	if (ispif->clk_idx == 1) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_clk_info, ispif->clk,
			ispif->num_clk, 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	if (ispif->clk_idx == 2) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	/* Turn OFF regulators after enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 0);
	if (rc < 0) {
		pr_err("%s: ispif disable regulator failed", __func__);
			return -EFAULT;
	}

	return rc;
}
예제 #5
0
static int msm_ispif_config(struct ispif_device *ispif,
	struct msm_ispif_param_data *params)
{
	int rc = 0, i = 0;
	uint16_t cid_mask;
	enum msm_ispif_intftype intftype;
	enum msm_ispif_vfe_intf vfe_intf;

	BUG_ON(!ispif);
	BUG_ON(!params);

	if (ispif->ispif_state != ISPIF_POWER_UP) {
		pr_err("%s: ispif invalid state %d\n", __func__,
			ispif->ispif_state);
		rc = -EPERM;
		return rc;
	}
	if (params->num > MAX_PARAM_ENTRIES) {
		pr_err("%s: invalid param entries %d\n", __func__,
			params->num);
		rc = -EINVAL;
		return rc;
	}

	for (i = 0; i < params->num; i++) {
		vfe_intf = params->entries[i].vfe_intf;
		if (!msm_ispif_is_intf_valid(ispif->csid_version,
				vfe_intf)) {
			pr_err("%s: invalid interface type\n", __func__);
			return -EINVAL;
		}
		msm_camera_io_w(0x0, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_0(vfe_intf));
		msm_camera_io_w(0x0, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_1(vfe_intf));
		msm_camera_io_w_mb(0x0, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_2(vfe_intf));
	}

	for (i = 0; i < params->num; i++) {
		intftype = params->entries[i].intftype;

		vfe_intf = params->entries[i].vfe_intf;

		CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__,
			intftype, vfe_intf, params->entries[i].csid);

		if ((intftype >= INTF_MAX) ||
			(vfe_intf >=  ispif->vfe_info.num_vfe) ||
			(ispif->csid_version <= CSID_VERSION_V22 &&
			(vfe_intf > VFE0))) {
			pr_err("%s: VFEID %d and CSID version %d mismatch\n",
				__func__, vfe_intf, ispif->csid_version);
			return -EINVAL;
		}

		if (ispif->csid_version >= CSID_VERSION_V30)
				msm_ispif_select_clk_mux(ispif, intftype,
				params->entries[i].csid, vfe_intf);

		rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf);
		if (rc) {
			pr_err("%s:validate_intf_status failed, rc = %d\n",
				__func__, rc);
			return rc;
		}

		msm_ispif_sel_csid_core(ispif, intftype,
			params->entries[i].csid, vfe_intf);
		cid_mask = msm_ispif_get_cids_mask_from_cfg(
				&params->entries[i]);
		msm_ispif_enable_intf_cids(ispif, intftype,
			cid_mask, vfe_intf, 1);
		if (params->entries[i].crop_enable)
			msm_ispif_enable_crop(ispif, intftype, vfe_intf,
				params->entries[i].crop_start_pixel,
				params->entries[i].crop_end_pixel);
	}

	for (vfe_intf = 0; vfe_intf < 2; vfe_intf++) {
		msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_0(vfe_intf));

		msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_0(vfe_intf));

		msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_1(vfe_intf));

		msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_1(vfe_intf));

		msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_MASK_2(vfe_intf));

		msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_2(vfe_intf));
	}

	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);

	return rc;
}
/* Later we can separate the rotation and scaler calc. If
*  rotation is enabled, simply swap the destination dimension.
*  And then pass the already swapped output size to this
*  function. */
static int vpe_update_scaler(struct msm_pp_crop *pcrop)
{
	uint32_t out_ROI_width, out_ROI_height;
	uint32_t src_ROI_width, src_ROI_height;

	/*
	* phase_step_x, phase_step_y, phase_init_x and phase_init_y
	* are represented in fixed-point, unsigned 3.29 format
	*/
	uint32_t phase_step_x = 0;
	uint32_t phase_step_y = 0;
	uint32_t phase_init_x = 0;
	uint32_t phase_init_y = 0;

	uint32_t src_roi, src_x, src_y, src_xy, temp;
	uint32_t yscale_filter_sel, xscale_filter_sel;
	uint32_t scale_unit_sel_x, scale_unit_sel_y;
	uint64_t numerator, denominator;

	/* assumption is both direction need zoom. this can be
	improved. */
	temp =
		msm_camera_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET) | 0x3;
	msm_camera_io_w(temp, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET);

	src_ROI_width = pcrop->src_w;
	src_ROI_height = pcrop->src_h;
	out_ROI_width = pcrop->dst_w;
	out_ROI_height = pcrop->dst_h;

	D("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n",
		src_ROI_width, src_ROI_height, out_ROI_width,
		out_ROI_height);
	src_roi = (src_ROI_height << 16) + src_ROI_width;

	msm_camera_io_w(src_roi, vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET);

	src_x = pcrop->src_x;
	src_y = pcrop->src_y;

	D("src_x = %d, src_y=%d.\n", src_x, src_y);

	src_xy = src_y*(1<<16) + src_x;
	msm_camera_io_w(src_xy, vpe_ctrl->vpebase +
			VPE_SRC_XY_OFFSET);
	D("src_xy = %d, src_roi=%d.\n", src_xy, src_roi);

	/* decide whether to use FIR or M/N for scaling */
	if ((out_ROI_width == 1 && src_ROI_width < 4) ||
		(src_ROI_width < 4 * out_ROI_width - 3))
		scale_unit_sel_x = 0;/* use FIR scalar */
	else
		scale_unit_sel_x = 1;/* use M/N scalar */

	if ((out_ROI_height == 1 && src_ROI_height < 4) ||
		(src_ROI_height < 4 * out_ROI_height - 3))
		scale_unit_sel_y = 0;/* use FIR scalar */
	else
		scale_unit_sel_y = 1;/* use M/N scalar */

	/* calculate phase step for the x direction */

	/* if destination is only 1 pixel wide,
	the value of phase_step_x
	is unimportant. Assigning phase_step_x to
	src ROI width as an arbitrary value. */
	if (out_ROI_width == 1)
		phase_step_x = (uint32_t) ((src_ROI_width) <<
						SCALER_PHASE_BITS);

		/* if using FIR scalar */
	else if (scale_unit_sel_x == 0) {

		/* Calculate the quotient ( src_ROI_width - 1 )
			( out_ROI_width - 1)
			with u3.29 precision. Quotient is rounded up to
			the larger 29th decimal point*/
		numerator = (uint64_t)(src_ROI_width - 1) <<
			SCALER_PHASE_BITS;
		/* never equals to 0 because of the
			"(out_ROI_width == 1 )"*/
		denominator = (uint64_t)(out_ROI_width - 1);
		/* divide and round up to the larger 29th
			decimal point.*/
		phase_step_x = (uint32_t) vpe_do_div((numerator +
					denominator - 1), denominator);
	} else if (scale_unit_sel_x == 1) { /* if M/N scalar */
		/* Calculate the quotient ( src_ROI_width ) /
			( out_ROI_width)
			with u3.29 precision. Quotient is rounded down to the
			smaller 29th decimal point.*/
		numerator = (uint64_t)(src_ROI_width) <<
			SCALER_PHASE_BITS;
		denominator = (uint64_t)(out_ROI_width);
		phase_step_x =
			(uint32_t) vpe_do_div(numerator, denominator);
	}
	/* calculate phase step for the y direction */

	/* if destination is only 1 pixel wide, the value of
		phase_step_x is unimportant. Assigning phase_step_x
		to src ROI width as an arbitrary value. */
	if (out_ROI_height == 1)
		phase_step_y =
		(uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);

	/* if FIR scalar */
	else if (scale_unit_sel_y == 0) {
		/* Calculate the quotient ( src_ROI_height - 1 ) /
		( out_ROI_height - 1)
		with u3.29 precision. Quotient is rounded up to the
		larger 29th decimal point. */
		numerator = (uint64_t)(src_ROI_height - 1) <<
			SCALER_PHASE_BITS;
		/* never equals to 0 because of the "
		( out_ROI_height == 1 )" case */
		denominator = (uint64_t)(out_ROI_height - 1);
		/* Quotient is rounded up to the larger
		29th decimal point. */
		phase_step_y =
		(uint32_t) vpe_do_div(
			(numerator + denominator - 1), denominator);
	} else if (scale_unit_sel_y == 1) { /* if M/N scalar */
		/* Calculate the quotient ( src_ROI_height )
			( out_ROI_height)
			with u3.29 precision. Quotient is rounded down
			to the smaller 29th decimal point. */
		numerator = (uint64_t)(src_ROI_height) <<
			SCALER_PHASE_BITS;
		denominator = (uint64_t)(out_ROI_height);
		phase_step_y = (uint32_t) vpe_do_div(
			numerator, denominator);
	}

	/* decide which set of FIR coefficients to use */
	if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
		xscale_filter_sel = 0;
	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
		xscale_filter_sel = 1;
	else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
		xscale_filter_sel = 2;
	else
		xscale_filter_sel = 3;

	if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
		yscale_filter_sel = 0;
	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
		yscale_filter_sel = 1;
	else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
		yscale_filter_sel = 2;
	else
		yscale_filter_sel = 3;

	/* calculate phase init for the x direction */

	/* if using FIR scalar */
	if (scale_unit_sel_x == 0) {
		if (out_ROI_width == 1)
			phase_init_x =
				(uint32_t) ((src_ROI_width - 1) <<
							SCALER_PHASE_BITS);
		else
			phase_init_x = 0;
	} else if (scale_unit_sel_x == 1) /* M over N scalar  */
		phase_init_x = 0;

	/* calculate phase init for the y direction
	if using FIR scalar */
	if (scale_unit_sel_y == 0) {
		if (out_ROI_height == 1)
			phase_init_y =
			(uint32_t) ((src_ROI_height -
						1) << SCALER_PHASE_BITS);
		else
			phase_init_y = 0;
	} else if (scale_unit_sel_y == 1) /* M over N scalar   */
		phase_init_y = 0;

	D("phase step x = %d, step y = %d.\n",
		 phase_step_x, phase_step_y);
	D("phase init x = %d, init y = %d.\n",
		 phase_init_x, phase_init_y);

	msm_camera_io_w(phase_step_x, vpe_ctrl->vpebase +
			VPE_SCALE_PHASEX_STEP_OFFSET);
	msm_camera_io_w(phase_step_y, vpe_ctrl->vpebase +
			VPE_SCALE_PHASEY_STEP_OFFSET);

	msm_camera_io_w(phase_init_x, vpe_ctrl->vpebase +
			VPE_SCALE_PHASEX_INIT_OFFSET);

	msm_camera_io_w(phase_init_y, vpe_ctrl->vpebase +
			VPE_SCALE_PHASEY_INIT_OFFSET);

	return 1;
}
static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
	struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd,
	uint32_t *cfg_data, uint32_t cmd_len)
{
	if (!vfe_dev || !reg_cfg_cmd) {
		pr_err("%s:%d failed: vfe_dev %p reg_cfg_cmd %p\n", __func__,
			__LINE__, vfe_dev, reg_cfg_cmd);
		return -EINVAL;
	}
	if ((reg_cfg_cmd->cmd_type != VFE_CFG_MASK) &&
		(!cfg_data || !cmd_len)) {
		pr_err("%s:%d failed: cmd type %d cfg_data %p cmd_len %d\n",
			__func__, __LINE__, reg_cfg_cmd->cmd_type, cfg_data,
			cmd_len);
		return -EINVAL;
	}

	/* Validate input parameters */
	switch (reg_cfg_cmd->cmd_type) {
	case VFE_WRITE:
	case VFE_READ:
	case VFE_WRITE_MB: {
		if ((reg_cfg_cmd->u.rw_info.reg_offset >
			(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
			((reg_cfg_cmd->u.rw_info.reg_offset +
			reg_cfg_cmd->u.rw_info.len) >
			resource_size(vfe_dev->vfe_mem))) {
			pr_err("%s:%d reg_offset %d len %d res %d\n",
				__func__, __LINE__,
				reg_cfg_cmd->u.rw_info.reg_offset,
				reg_cfg_cmd->u.rw_info.len,
				(uint32_t)resource_size(vfe_dev->vfe_mem));
			return -EINVAL;
		}

		if ((reg_cfg_cmd->u.rw_info.cmd_data_offset >
			(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
			((reg_cfg_cmd->u.rw_info.cmd_data_offset +
			reg_cfg_cmd->u.rw_info.len) > cmd_len)) {
			pr_err("%s:%d cmd_data_offset %d len %d cmd_len %d\n",
				__func__, __LINE__,
				reg_cfg_cmd->u.rw_info.cmd_data_offset,
				reg_cfg_cmd->u.rw_info.len, cmd_len);
			return -EINVAL;
		}
		break;
	}

	case VFE_WRITE_DMI_16BIT:
	case VFE_WRITE_DMI_32BIT:
	case VFE_WRITE_DMI_64BIT:
	case VFE_READ_DMI_16BIT:
	case VFE_READ_DMI_32BIT:
	case VFE_READ_DMI_64BIT: {
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT ||
			reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
			if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <=
				reg_cfg_cmd->u.dmi_info.lo_tbl_offset) ||
				(reg_cfg_cmd->u.dmi_info.hi_tbl_offset -
				reg_cfg_cmd->u.dmi_info.lo_tbl_offset !=
				(sizeof(uint32_t)))) {
				pr_err("%s:%d hi %d lo %d\n",
					__func__, __LINE__,
					reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
					reg_cfg_cmd->u.dmi_info.hi_tbl_offset);
				return -EINVAL;
			}
			if (reg_cfg_cmd->u.dmi_info.len <= sizeof(uint32_t)) {
				pr_err("%s:%d len %d\n",
					__func__, __LINE__,
					reg_cfg_cmd->u.dmi_info.len);
			return -EINVAL;
		}
			if (((UINT_MAX -
				reg_cfg_cmd->u.dmi_info.hi_tbl_offset) <
				(reg_cfg_cmd->u.dmi_info.len -
				sizeof(uint32_t))) ||
				((reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
				reg_cfg_cmd->u.dmi_info.len -
				sizeof(uint32_t)) > cmd_len)) {
				pr_err("%s:%d hi_tbl_offset %d len %d cmd %d\n",
					__func__, __LINE__,
					reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
					reg_cfg_cmd->u.dmi_info.len, cmd_len);
				return -EINVAL;
			}
		}
		if ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset >
			(UINT_MAX - reg_cfg_cmd->u.dmi_info.len)) ||
			((reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
			reg_cfg_cmd->u.dmi_info.len) > cmd_len)) {
			pr_err("%s:%d lo_tbl_offset %d len %d cmd_len %d\n",
				__func__, __LINE__,
				reg_cfg_cmd->u.dmi_info.lo_tbl_offset,
				reg_cfg_cmd->u.dmi_info.len, cmd_len);
			return -EINVAL;
		}
		break;
	}

	default:
		break;
	}

	switch (reg_cfg_cmd->cmd_type) {
	case VFE_WRITE: {
		msm_camera_io_memcpy(vfe_dev->vfe_base +
			reg_cfg_cmd->u.rw_info.reg_offset,
			cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
			reg_cfg_cmd->u.rw_info.len);
		break;
	}
	case VFE_WRITE_MB: {
		msm_camera_io_memcpy_mb(vfe_dev->vfe_base +
			reg_cfg_cmd->u.rw_info.reg_offset,
			cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
			reg_cfg_cmd->u.rw_info.len);
		break;
	}
	case VFE_CFG_MASK: {
		uint32_t temp;
		if ((UINT_MAX - sizeof(temp) <
			reg_cfg_cmd->u.mask_info.reg_offset) ||
			(resource_size(vfe_dev->vfe_mem) <
			reg_cfg_cmd->u.mask_info.reg_offset +
			sizeof(temp))) {
			pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__);
			return -EINVAL;
		}
		temp = msm_camera_io_r(vfe_dev->vfe_base +
			reg_cfg_cmd->u.mask_info.reg_offset);
		temp &= ~reg_cfg_cmd->u.mask_info.mask;
		temp |= reg_cfg_cmd->u.mask_info.val;
		msm_camera_io_w(temp, vfe_dev->vfe_base +
			reg_cfg_cmd->u.mask_info.reg_offset);
		break;
	}
	case VFE_WRITE_DMI_16BIT:
	case VFE_WRITE_DMI_32BIT:
	case VFE_WRITE_DMI_64BIT: {
		int i;
		uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
		uint32_t hi_val, lo_val, lo_val1;
		if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
			hi_tbl_ptr = cfg_data +
				reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
		}

		lo_tbl_ptr = cfg_data +
			reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;

		if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
			reg_cfg_cmd->u.dmi_info.len = reg_cfg_cmd->u.dmi_info.len/2;
		}
		for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
			lo_val = *lo_tbl_ptr++;
			if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) {
				lo_val1 = lo_val & 0x0000FFFF;
				lo_val = (lo_val & 0xFFFF0000)>>16;
				msm_camera_io_w(lo_val1, vfe_dev->vfe_base +
					vfe_dev->hw_info->dmi_reg_offset + 0x4);
			} else if (reg_cfg_cmd->cmd_type ==
					   VFE_WRITE_DMI_64BIT) {
				lo_tbl_ptr++;
				hi_val = *hi_tbl_ptr;
				hi_tbl_ptr = hi_tbl_ptr + 2;
				msm_camera_io_w(hi_val, vfe_dev->vfe_base +
					vfe_dev->hw_info->dmi_reg_offset);
			}
			msm_camera_io_w(lo_val, vfe_dev->vfe_base +
				vfe_dev->hw_info->dmi_reg_offset + 0x4);
		}
		break;
	}
예제 #8
0
static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
	void *data)
{
	struct ispif_device *ispif = (struct ispif_device *)data;

	BUG_ON(!ispif);
	BUG_ON(!out);

	out[VFE0].ispifIrqStatus0 = msm_camera_io_r(ispif->base +
		ISPIF_VFE_m_IRQ_STATUS_0(VFE0));
	msm_camera_io_w(out[VFE0].ispifIrqStatus0,
		ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE0));

	out[VFE0].ispifIrqStatus1 = msm_camera_io_r(ispif->base +
		ISPIF_VFE_m_IRQ_STATUS_1(VFE0));
	msm_camera_io_w(out[VFE0].ispifIrqStatus1,
		ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE0));

	out[VFE0].ispifIrqStatus2 = msm_camera_io_r(ispif->base +
		ISPIF_VFE_m_IRQ_STATUS_2(VFE0));
	msm_camera_io_w_mb(out[VFE0].ispifIrqStatus2,
		ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE0));

	if (ispif->vfe_info.num_vfe > 1) {
		out[VFE1].ispifIrqStatus0 = msm_camera_io_r(ispif->base +
			ISPIF_VFE_m_IRQ_STATUS_0(VFE1));
		msm_camera_io_w(out[VFE1].ispifIrqStatus0,
			ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE1));

		out[VFE1].ispifIrqStatus1 = msm_camera_io_r(ispif->base +
			ISPIF_VFE_m_IRQ_STATUS_1(VFE1));
		msm_camera_io_w(out[VFE1].ispifIrqStatus1,
				ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE1));

		out[VFE1].ispifIrqStatus2 = msm_camera_io_r(ispif->base +
			ISPIF_VFE_m_IRQ_STATUS_2(VFE1));
		msm_camera_io_w_mb(out[VFE1].ispifIrqStatus2,
			ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE1));
	}
	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
	ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);

	if (out[VFE0].ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
		if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ)
			complete(&ispif->reset_complete[VFE0]);

		if (out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
			pr_err("%s: VFE0 pix0 overflow.\n", __func__);

		if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ)
			pr_err("%s: VFE0 rdi0 overflow.\n", __func__);

		if (out[VFE0].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ)
			pr_err("%s: VFE0 rdi1 overflow.\n", __func__);

		if (out[VFE0].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ)
			pr_err("%s: VFE0 rdi2 overflow.\n", __func__);

		ispif_process_irq(ispif, out, VFE0);
	}
	if (ispif->hw_num_isps > 1) {
		if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ)
			complete(&ispif->reset_complete[VFE1]);

		if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ)
			pr_err("%s: VFE1 pix0 overflow.\n", __func__);

		if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ)
			pr_err("%s: VFE1 rdi0 overflow.\n", __func__);

		if (out[VFE1].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ)
			pr_err("%s: VFE1 rdi1 overflow.\n", __func__);

		if (out[VFE1].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ)
			pr_err("%s: VFE1 rdi2 overflow.\n", __func__);

		ispif_process_irq(ispif, out, VFE1);
	}
}
static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
	struct msm_camera_csiphy_params *csiphy_params)
{
	int rc = 0;
	int j = 0, curr_lane = 0;
	uint32_t val = 0, clk_rate = 0, round_rate = 0;
	uint8_t lane_cnt = 0;
	uint16_t lane_mask = 0;
	void __iomem *csiphybase;
	uint8_t csiphy_id = csiphy_dev->pdev->id;
	int32_t lane_val = 0, lane_right = 0, num_lanes = 0;
	struct clk **csid_phy_clk_ptr;
	int ratio = 1;

	csiphybase = csiphy_dev->base;
	if (!csiphybase) {
		pr_err("%s: csiphybase NULL\n", __func__);
		return -EINVAL;
	}

	csiphy_dev->lane_mask[csiphy_id] |= csiphy_params->lane_mask;
	lane_mask = csiphy_dev->lane_mask[csiphy_id];
	lane_cnt = csiphy_params->lane_cnt;
	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
		pr_err("%s: unsupported lane cnt %d\n",
			__func__, csiphy_params->lane_cnt);
		return rc;
	}

	csid_phy_clk_ptr = csiphy_dev->csiphy_clk;
	if (!csid_phy_clk_ptr) {
		pr_err("csiphy_timer_src_clk get failed\n");
		return -EINVAL;
	}

	clk_rate = (csiphy_params->csiphy_clk > 0)
			? csiphy_params->csiphy_clk :
			csiphy_dev->csiphy_max_clk;
	round_rate = clk_round_rate(
			csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index],
			clk_rate);
	if (round_rate >= csiphy_dev->csiphy_max_clk)
		round_rate = csiphy_dev->csiphy_max_clk;
	else {
		ratio = csiphy_dev->csiphy_max_clk/round_rate;
		csiphy_params->settle_cnt = csiphy_params->settle_cnt/ratio;
	}

	CDBG("set from usr csiphy_clk clk_rate = %u round_rate = %u\n",
			clk_rate, round_rate);
	rc = clk_set_rate(
		csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index],
		round_rate);
	if (rc < 0) {
		pr_err("csiphy_timer_src_clk set failed\n");
		return rc;
	}

	CDBG("%s csiphy_params, mask = 0x%x cnt = %d\n",
		__func__,
		csiphy_params->lane_mask,
		csiphy_params->lane_cnt);
	CDBG("%s csiphy_params, settle cnt = 0x%x csid %d\n",
		__func__, csiphy_params->settle_cnt,
		csiphy_params->csid_core);

	if (csiphy_dev->hw_version >= CSIPHY_VERSION_V30) {
		val = msm_camera_io_r(csiphy_dev->clk_mux_base);
		if (csiphy_params->combo_mode &&
			(csiphy_params->lane_mask & 0x18) == 0x18) {
			val &= ~0xf0;
			val |= csiphy_params->csid_core << 4;
		} else {
			val &= ~0xf;
			val |= csiphy_params->csid_core;
		}
		msm_camera_io_w(val, csiphy_dev->clk_mux_base);
		CDBG("%s clk mux addr %p val 0x%x\n", __func__,
			csiphy_dev->clk_mux_base, val);
		mb();
	}
	msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg->
		csiphy_reg.mipi_csiphy_glbl_t_init_cfg0_addr);
	msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg->
		csiphy_reg.mipi_csiphy_t_wakeup_cfg0_addr);

	if (csiphy_dev->hw_version < CSIPHY_VERSION_V30) {
		val = 0x3;
		msm_camera_io_w((lane_mask << 2) | val,
				csiphybase +
				csiphy_dev->ctrl_reg->
				csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr);
		msm_camera_io_w(0x10, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnck_cfg2_addr);
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnck_cfg3_addr);
		msm_camera_io_w(0x24,
			csiphybase + csiphy_dev->ctrl_reg->
			csiphy_reg.mipi_csiphy_interrupt_mask0_addr);
		msm_camera_io_w(0x24,
			csiphybase + csiphy_dev->ctrl_reg->
			csiphy_reg.mipi_csiphy_interrupt_clear0_addr);
	} else {
		val = 0x1;
		msm_camera_io_w((lane_mask << 1) | val,
				csiphybase +
				csiphy_dev->ctrl_reg->
				csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr);
		msm_camera_io_w(csiphy_params->combo_mode <<
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_mode_config_shift,
			csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_glbl_reset_addr);
	}

	lane_mask &= 0x1f;
	while (lane_mask & 0x1f) {
		if (!(lane_mask & 0x1)) {
			j++;
			lane_mask >>= 1;
			continue;
		}
		msm_camera_io_w(0x10,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg2_addr + 0x40*j);
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg3_addr + 0x40*j);
		/* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) begin*/
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase + csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_lnn_cfg4_addr + 0x40*j);
		/* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) end*/
		msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_val, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_addr + 0x4*j);
		msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_mask_val, csiphybase +
			csiphy_dev->ctrl_reg->csiphy_reg.
			mipi_csiphy_interrupt_clear_addr + 0x4*j);
		if (csiphy_dev->is_3_1_20nm_hw == 1) {
			if (j > CLK_LANE_OFFSET) {
				lane_right = 0x8;
				num_lanes = (lane_cnt - curr_lane)
					<< NUM_LANES_OFFSET;
				if (lane_cnt < curr_lane) {
					pr_err("%s: Lane_cnt is less than curr_lane number\n",
						__func__);
					return -EINVAL;
				}
				lane_val = lane_right|num_lanes;
			} else if (j == 1) {
				lane_val = 0x4;
			}
			if (csiphy_params->combo_mode == 1) {
				/*
				* In the case of combo mode, the clock is always
				* 4th lane for the second sensor.
				* So check whether the sensor is of one lane
				* sensor and curr_lane for 0.
				*/
				if (curr_lane == 0 &&
					((csiphy_params->lane_mask &
						0x18) == 0x18))
					lane_val = 0x4;
			}
			msm_camera_io_w(lane_val, csiphybase +
				csiphy_dev->ctrl_reg->csiphy_reg.
				mipi_csiphy_lnn_misc1_addr + 0x40*j);
			msm_camera_io_w(0x17, csiphybase +
				csiphy_dev->ctrl_reg->csiphy_reg.
				mipi_csiphy_lnn_test_imp + 0x40*j);
			curr_lane++;
		}
		j++;
		lane_mask >>= 1;
	}
static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
			       struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd,
			       uint32_t *cfg_data, uint32_t cmd_len)
{
	switch (reg_cfg_cmd->cmd_type) {
	case VFE_WRITE: {
		if (resource_size(vfe_dev->vfe_mem) <
		    (reg_cfg_cmd->u.rw_info.reg_offset +
		     reg_cfg_cmd->u.rw_info.len)) {
			pr_err("%s: Invalid length\n", __func__);
			return -EINVAL;
		}
		msm_camera_io_memcpy(vfe_dev->vfe_base +
				     reg_cfg_cmd->u.rw_info.reg_offset,
				     cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset / 4,
				     reg_cfg_cmd->u.rw_info.len);
		break;
	}
	case VFE_WRITE_MB: {
		uint32_t *data_ptr = cfg_data +
				     reg_cfg_cmd->u.rw_info.cmd_data_offset / 4;
		msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base +
				   reg_cfg_cmd->u.rw_info.reg_offset);
		break;
	}
	case VFE_CFG_MASK: {
		uint32_t temp;
		temp = msm_camera_io_r(vfe_dev->vfe_base +
				       reg_cfg_cmd->u.mask_info.reg_offset);
		temp &= ~reg_cfg_cmd->u.mask_info.mask;
		temp |= reg_cfg_cmd->u.mask_info.val;
		msm_camera_io_w(temp, vfe_dev->vfe_base +
				reg_cfg_cmd->u.mask_info.reg_offset);
		break;
	}
	case VFE_WRITE_DMI_16BIT:
	case VFE_WRITE_DMI_32BIT:
	case VFE_WRITE_DMI_64BIT: {
		int i;
		uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
		uint32_t hi_val, lo_val, lo_val1;
		if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
			if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
			    reg_cfg_cmd->u.dmi_info.len > cmd_len) {
				pr_err("Invalid Hi Table out of bounds\n");
				return -EINVAL;
			}
			hi_tbl_ptr = cfg_data +
				     reg_cfg_cmd->u.dmi_info.hi_tbl_offset / 4;
		}

		if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
		    reg_cfg_cmd->u.dmi_info.len > cmd_len) {
			pr_err("Invalid Lo Table out of bounds\n");
			return -EINVAL;
		}
		lo_tbl_ptr = cfg_data +
			     reg_cfg_cmd->u.dmi_info.lo_tbl_offset / 4;

		if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT)
			reg_cfg_cmd->u.dmi_info.len =
				reg_cfg_cmd->u.dmi_info.len / 2;

		for (i = 0; i < reg_cfg_cmd->u.dmi_info.len / 4; i++) {
			lo_val = *lo_tbl_ptr++;
			if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) {
				lo_val1 = lo_val & 0x0000FFFF;
				lo_val = (lo_val & 0xFFFF0000) >> 16;
				msm_camera_io_w(lo_val1, vfe_dev->vfe_base +
						vfe_dev->hw_info->dmi_reg_offset + 0x4);
			} else if (reg_cfg_cmd->cmd_type ==
				   VFE_WRITE_DMI_64BIT) {
				lo_tbl_ptr++;
				hi_val = *hi_tbl_ptr;
				hi_tbl_ptr = hi_tbl_ptr + 2;
				msm_camera_io_w(hi_val, vfe_dev->vfe_base +
						vfe_dev->hw_info->dmi_reg_offset);
			}
			msm_camera_io_w(lo_val, vfe_dev->vfe_base +
					vfe_dev->hw_info->dmi_reg_offset + 0x4);
		}
		break;
	}
int msm_camio_csi_config(struct msm_camera_csi_params *csi_params)
{
	int rc = 0;
	uint32_t val = 0;
	int i;

	CDBG("msm_camio_csi_config\n");

	/* SOT_ECC_EN enable error correction for SYNC (data-lane) */
	msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL);

	/* SW_RST to the CSI core */
	msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK,
		csibase + MIPI_PROTOCOL_CONTROL);

	/* PROTOCOL CONTROL */
	val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK |
		MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK |
		MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK;
	val |= (uint32_t)(csi_params->data_format) <<
		MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT;
	val |= csi_params->dpcm_scheme <<
		MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT;
	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
	msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL);

	/* SW CAL EN */
	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
		(0x1 <<
		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
	msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL);

	/* settle_cnt is very sensitive to speed!
	increase this value to run at higher speeds */
	val = (csi_params->settle_cnt <<
			MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
	for (i = 0; i < csi_params->lane_cnt; i++)
		msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2 + i * 4);

	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
		(0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT);
	CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val);
	msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL);

	val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT;
	msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL);

	val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) |
		(0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT);
	CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val);
	msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL);

	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL);
	msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL);

	/* halcyon only supports 1 or 2 lane */
	switch (csi_params->lane_cnt) {
	case 1:
		msm_camera_io_w(csi_params->lane_assign << 8 | 0x4,
			csibase + MIPI_CAMERA_CNTL);
		break;
	case 2:
		msm_camera_io_w(csi_params->lane_assign << 8 | 0x5,
			csibase + MIPI_CAMERA_CNTL);
		break;
	case 3:
		msm_camera_io_w(csi_params->lane_assign << 8 | 0x6,
			csibase + MIPI_CAMERA_CNTL);
		break;
	case 4:
		msm_camera_io_w(csi_params->lane_assign << 8 | 0x7,
			csibase + MIPI_CAMERA_CNTL);
		break;
	}

	/* mask out ID_ERROR[19], DATA_CMM_ERR[11]
	and CLK_CMM_ERR[10] - de-featured */
	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_MASK);
	/*clear IRQ bits*/
	msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_STATUS);

	return rc;
}
예제 #12
0
static int msm_csid_release(struct csid_device *csid_dev)
{
	uint32_t irq;
/* LGE_CHANGE_S [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */
	wake_unlock(&csid_dev->csid_wake_lock);
/* LGE_CHANGE_E [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */

	if (csid_dev->csid_state != CSID_POWER_UP) {
		pr_err("%s: csid invalid state %d\n", __func__,
			csid_dev->csid_state);
		return -EINVAL;
	}

	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
	msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);

	disable_irq(csid_dev->irq->start);

	if (csid_dev->hw_version == CSID_VERSION_V20) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else if (csid_dev->hw_version == CSID_VERSION_V22) {
		msm_cam_clk_enable(&csid_dev->pdev->dev,
			csid_8610_clk_info,
			csid_dev->csid_clk,
			ARRAY_SIZE(csid_8610_clk_info), 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	} else if (csid_dev->hw_version >= CSID_VERSION_V30) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info,
			csid_dev->csid_clk, ARRAY_SIZE(csid_8974_clk_info), 0);

		msm_camera_enable_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);

		msm_camera_config_vreg(&csid_dev->pdev->dev,
			csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
			NULL, 0, &csid_dev->csi_vdd, 0);
	}

	iounmap(csid_dev->base);
	csid_dev->base = NULL;
	csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;
}
예제 #13
0
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif,
	struct msm_ispif_param_data *params)
{
	int rc = 0, i;
	long timeout = 0;
	uint16_t cid_mask;
	enum msm_ispif_intftype intftype;
	enum msm_ispif_vfe_intf vfe_intf;
	uint32_t vfe_mask = 0;
	uint32_t intf_addr;

	if (ispif->ispif_state != ISPIF_POWER_UP) {
		pr_err("%s: ispif invalid state %d\n", __func__,
			ispif->ispif_state);
		rc = -EPERM;
		return rc;
	}
	if (params->num > MAX_PARAM_ENTRIES) {
		pr_err("%s: invalid param entries %d\n", __func__,
			params->num);
		rc = -EINVAL;
		return rc;
	}

	for (i = 0; i < params->num; i++) {
		vfe_intf = params->entries[i].vfe_intf;
		if (vfe_intf >= VFE_MAX) {
			pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__,
				__LINE__, i, vfe_intf);
			return -EINVAL;
		}
		vfe_mask |= (1 << vfe_intf);
	}

	/* Turn ON regulators before enabling the clocks*/
	rc = msm_ispif_set_regulator(ispif, 1);
	if (rc < 0) {
		pr_err("%s: ispif enable regulator failed", __func__);
			return -EFAULT;
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
			__func__, rc);
			goto disable_regulator;
	}

	if (vfe_mask & (1 << VFE0)) {
		init_completion(&ispif->reset_complete[VFE0]);
		/* initiate reset of ISPIF */
		msm_camera_io_w(0x00001FF9,
				ispif->base + ISPIF_RST_CMD_ADDR);
	}

	if (vfe_mask & (1 << VFE0)) {
		timeout = wait_for_completion_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
		if (timeout <= 0) {
			pr_err("%s: VFE0 reset wait timeout\n", __func__);
			rc = -ETIMEDOUT;
			goto disable_clk;
		}
	}

	if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) {
			init_completion(&ispif->reset_complete[VFE1]);
			msm_camera_io_w(0x00001FF9,
				ispif->base + ISPIF_RST_CMD_1_ADDR);
	}

	if (ispif->hw_num_isps > 1  && (vfe_mask & (1 << VFE1))) {
		timeout = wait_for_completion_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
			rc = -ETIMEDOUT;
			goto disable_clk;
		}
	}

	pr_info("%s: ISPIF reset hw done, Restarting", __func__);
	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 0);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
			__func__, rc);
			goto disable_regulator;
	}
	/* Turn OFF regulators after disabling clocks */
	rc = msm_ispif_set_regulator(ispif, 0);
	if (rc < 0) {
		pr_err("%s: ispif disable regulator failed", __func__);
		rc = -EFAULT;
		goto end;
	}

	for (i = 0; i < params->num; i++) {
		intftype = params->entries[i].intftype;
		vfe_intf = params->entries[i].vfe_intf;

		switch (params->entries[0].intftype) {
		case PIX0:
			intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0);
			break;
		case RDI0:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0);
			break;
		case PIX1:
			intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1);
			break;
		case RDI1:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1);
			break;
		case RDI2:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2);
			break;
		default:
			pr_err("%s: invalid intftype=%d\n", __func__,
			params->entries[i].intftype);
			rc = -EPERM;
			goto end;
		}

		msm_ispif_intf_cmd(ispif,
			ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params);
	}

	for (i = 0; i < params->num; i++) {
		intftype = params->entries[i].intftype;

		vfe_intf = params->entries[i].vfe_intf;


		cid_mask = msm_ispif_get_cids_mask_from_cfg(
			&params->entries[i]);

		msm_ispif_enable_intf_cids(ispif, intftype,
			cid_mask, vfe_intf, 1);
	}
	return rc;

disable_clk:
	msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_clk_info, ispif->clk,
		ispif->num_clk, 0);
disable_regulator:
	/* Turn OFF regulators */
	msm_ispif_set_regulator(ispif, 0);
end:
	return rc;
}
예제 #14
0
void msm_csid_reset(struct csid_device *csid_dev)
{
	msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
	wait_for_completion_interruptible(&csid_dev->reset_complete);
	return;
}
static int msm_ispif_intf_reset(struct ispif_device *ispif,
	struct msm_ispif_param_data *params)
{

	int i, rc = 0;
	enum msm_ispif_intftype intf_type;
	int vfe_intf = 0;
	uint32_t data = 0;

	for (i = 0; i < params->num; i++) {
		data = STROBED_RST_EN;
		vfe_intf = params->entries[i].vfe_intf;
		intf_type = params->entries[i].intftype;
		ispif->sof_count[params->entries[i].vfe_intf].
			sof_cnt[intf_type] = 0;

		switch (intf_type) {
		case PIX0:
			data |= (PIX_0_VFE_RST_STB | PIX_0_CSID_RST_STB);
			break;
		case RDI0:
			data |= (RDI_0_VFE_RST_STB | RDI_0_CSID_RST_STB);
			break;
		case PIX1:
			data |= (PIX_1_VFE_RST_STB | PIX_1_CSID_RST_STB);
			break;
		case RDI1:
			data |= (RDI_1_VFE_RST_STB | RDI_1_CSID_RST_STB);
			break;
		case RDI2:
			data |= (RDI_2_VFE_RST_STB | RDI_2_CSID_RST_STB);
			break;
		default:
			rc = -EINVAL;
			break;
		}
		if (data > 0x1) {
			unsigned long jiffes = msecs_to_jiffies(500);
			long lrc = 0;
			unsigned long flags;

			spin_lock_irqsave(
				&ispif->auto_complete_lock, flags);
			ispif->wait_timeout[vfe_intf] = 0;
			init_completion(&ispif->reset_complete[vfe_intf]);
			spin_unlock_irqrestore(
				&ispif->auto_complete_lock, flags);

			if (vfe_intf == VFE0)
				msm_camera_io_w(data, ispif->base +
					ISPIF_RST_CMD_ADDR);
			else
				msm_camera_io_w(data, ispif->base +
					ISPIF_RST_CMD_1_ADDR);
			lrc = wait_for_completion_interruptible_timeout(
				&ispif->reset_complete[vfe_intf], jiffes);
			if (lrc < 0 || !lrc) {
				pr_err("%s: wait timeout ret = %ld, vfe_id = %d\n",
					__func__, lrc, vfe_intf);
				rc = -EIO;

				spin_lock_irqsave(
					&ispif->auto_complete_lock, flags);
				ispif->wait_timeout[vfe_intf] = 1;
				spin_unlock_irqrestore(
					&ispif->auto_complete_lock, flags);
			}
		}
	}

	return rc;
}
예제 #16
0
int msm_csid_release(struct csid_device *csid_dev, uint32_t bypass)
{
	uint32_t irq;
	uint8_t core_id = 0;

	if (csid_dev->csid_state != CSID_POWER_UP) {
		pr_err("%s: csid invalid state %d\n", __func__,
			csid_dev->csid_state);
		return -EINVAL;
	}

	pr_err("%s - %d", __func__, csid_dev->refcnt-1);

	/* skip if reserved */
	if (csid_dev->refcnt) {
		if (!csid_dev->reserved_adp) {
			msm_csid_soft_reset(csid_dev);
			pr_err("%s - resetting csid", __func__);
		}

		if (--csid_dev->refcnt)
			return 0;
	} else {
		pr_err("%s refcnt already 0!", __func__);
	}

	if (csid_dev->reserved_adp) {
		pr_err("%s - csid reserved!", __func__);
		return 0;
	}

	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
	msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);

	disable_irq(csid_dev->irq->start);

	if (csid_dev->hw_version <= CSID_VERSION_V2) {
		msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
			csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
		if (!bypass) {
			msm_camera_enable_vreg(&csid_dev->pdev->dev,
					csid_8960_vreg_info,
					ARRAY_SIZE(csid_8960_vreg_info),
					NULL, 0, &csid_dev->csi_vdd, 0);

			msm_camera_config_vreg(&csid_dev->pdev->dev,
					csid_8960_vreg_info,
					ARRAY_SIZE(csid_8960_vreg_info),
					NULL, 0, &csid_dev->csi_vdd, 0);
		}
	} else if (csid_dev->hw_version == CSID_VERSION_V3) {
		core_id = csid_dev->pdev->id;
		if (core_id)
			msm_cam_clk_enable(&csid_dev->pdev->dev,
				csid_8974_clk_info[core_id].clk_info,
				csid_dev->csid_clk,
				csid_8974_clk_info[core_id].num_clk_info, 0);

		msm_cam_clk_enable(&csid_dev->pdev->dev,
			csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk,
			csid_8974_clk_info[0].num_clk_info, 0);
		if (!bypass) {
			msm_camera_enable_vreg(&csid_dev->pdev->dev,
					csid_8974_vreg_info,
					ARRAY_SIZE(csid_8974_vreg_info),
					NULL, 0, &csid_dev->csi_vdd, 0);

			msm_camera_config_vreg(&csid_dev->pdev->dev,
					csid_8974_vreg_info,
					ARRAY_SIZE(csid_8974_vreg_info),
					NULL, 0, &csid_dev->csi_vdd, 0);
		}
	}

	iounmap(csid_dev->base);
	csid_dev->base = NULL;
	csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;
}
static int msm_ispif_reset(struct ispif_device *ispif)
{
	int rc = 0;
	long lrc = 0;
	unsigned long jiffes = msecs_to_jiffies(500);
	unsigned long flags;

	spin_lock_irqsave(&ispif->auto_complete_lock, flags);
	ispif->wait_timeout[VFE0] = 0;
	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->csid_version >= CSID_VERSION_V3 &&
		ispif->vfe_info.num_vfe > 1) {
		ispif->wait_timeout[VFE1] = 0;
		init_completion(&ispif->reset_complete[VFE1]);
	}
	spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);

	BUG_ON(!ispif);

	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
	msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
		ispif->base + ISPIF_VFE_m_INTF_CMD_0(0));

	msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR);

	lrc = wait_for_completion_interruptible_timeout(
		&ispif->reset_complete[VFE0], jiffes);

	if (lrc < 0 || !lrc) {
		pr_err("%s: wait timeout ret = %ld, vfeid = %d\n",
			__func__, lrc, VFE0);
		rc = -EIO;

		spin_lock_irqsave(&ispif->auto_complete_lock, flags);
		ispif->wait_timeout[VFE0] = 1;
		spin_unlock_irqrestore(&ispif->auto_complete_lock, flags);

		goto end;
	}

	if (ispif->csid_version >= CSID_VERSION_V3 &&
		ispif->vfe_info.num_vfe > 1) {
		msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base +
			ISPIF_RST_CMD_1_ADDR);

		lrc = wait_for_completion_interruptible_timeout(
			&ispif->reset_complete[VFE1], jiffes);

		if (lrc < 0 || !lrc) {
			pr_err("%s: wait timeout ret = %ld, vfeid = %d\n",
				__func__, lrc, VFE1);
			rc = -EIO;

			spin_lock_irqsave(&ispif->auto_complete_lock, flags);
			ispif->wait_timeout[VFE1] = 1;
			spin_unlock_irqrestore(&ispif->auto_complete_lock,
				flags);
		}

	}

end:
	return rc;
}
예제 #18
0
static int msm_ispif_reset_hw(struct ispif_device *ispif)
{
	int rc = 0;
	long timeout = 0;
	struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)];
	struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)];
	ispif->clk_idx = 0;

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 1);
	if (rc < 0) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 1);
		if (rc < 0) {
			pr_err("%s: cannot enable clock, error = %d",
				__func__, rc);
		} else {
			/* This is set when device is 8x26 */
			ispif->clk_idx = 2;
		}
	} else {
		/* This is set when device is 8974 */
		ispif->clk_idx = 1;
	}

	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->hw_num_isps > 1)
		init_completion(&ispif->reset_complete[VFE1]);

	/* initiate reset of ISPIF */
	msm_camera_io_w(ISPIF_RST_CMD_MASK,
				ispif->base + ISPIF_RST_CMD_ADDR);
	if (ispif->hw_num_isps > 1)
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
					ispif->base + ISPIF_RST_CMD_1_ADDR);

	timeout = wait_for_completion_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
	CDBG("%s: VFE0 done\n", __func__);

	if (timeout <= 0) {
		pr_err("%s: VFE0 reset wait timeout\n", __func__);
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8974_reset_clk_info, reset_clk,
			ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
		if (rc < 0) {
			rc = msm_cam_clk_enable(&ispif->pdev->dev,
				ispif_8626_reset_clk_info, reset_clk1,
				ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
			if (rc < 0)
				pr_err("%s: VFE0 reset wait timeout\n",
					 __func__);
		}
		return -ETIMEDOUT;
	}

	if (ispif->hw_num_isps > 1) {
		timeout = wait_for_completion_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		CDBG("%s: VFE1 done\n", __func__);
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
			msm_cam_clk_enable(&ispif->pdev->dev,
				ispif_8974_reset_clk_info, reset_clk,
				ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
			return -ETIMEDOUT;
		}
	}

	if (ispif->clk_idx == 1) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8974_reset_clk_info, reset_clk,
			ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	if (ispif->clk_idx == 2) {
		rc = msm_cam_clk_enable(&ispif->pdev->dev,
			ispif_8626_reset_clk_info, reset_clk1,
			ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
		if (rc < 0) {
			pr_err("%s: cannot disable clock, error = %d",
				__func__, rc);
		}
	}

	return rc;
}
예제 #19
0
static int msm_ispif_reset_hw(struct ispif_device *ispif)
{
	int rc = 0;
	long timeout = 0;
	struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)];

	if (ispif->csid_version < CSID_VERSION_V30) {
		/* currently reset is done only for 8974 */
		return 0;

	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
			__func__, rc);
	}

	init_completion(&ispif->reset_complete[VFE0]);
	if (ispif->hw_num_isps > 1)
		init_completion(&ispif->reset_complete[VFE1]);

	/* initiate reset of ISPIF */
	msm_camera_io_w(ISPIF_RST_CMD_MASK,
				ispif->base + ISPIF_RST_CMD_ADDR);
	if (ispif->hw_num_isps > 1)
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
					ispif->base + ISPIF_RST_CMD_1_ADDR);

	timeout = wait_for_completion_interruptible_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
	CDBG("%s: VFE0 done\n", __func__);
	if (timeout <= 0) {
		pr_err("%s: VFE0 reset wait timeout\n", __func__);
		rc = -ETIMEDOUT;
		goto end;
	}

	if (ispif->hw_num_isps > 1) {
		timeout = wait_for_completion_interruptible_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		CDBG("%s: VFE1 done\n", __func__);
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
			rc = -ETIMEDOUT;
			goto end;
		}
	}
	pr_info("%s: ISPIF reset hw done", __func__);
end:
	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
	if (rc < 0) {
		pr_err("%s: cannot disable clock, error = %d",
			__func__, rc);
	}
	return rc;
}
예제 #20
0
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif,
	struct msm_ispif_param_data *params)
{
	int rc = 0, i;
	long timeout = 0;
	uint16_t cid_mask;
	enum msm_ispif_intftype intftype;
	enum msm_ispif_vfe_intf vfe_intf;
	uint32_t vfe_mask = 0;
	uint32_t intf_addr;
	struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)];

	if (ispif->ispif_state != ISPIF_POWER_UP) {
		pr_err("%s: ispif invalid state %d\n", __func__,
			ispif->ispif_state);
		rc = -EPERM;
		return rc;
	}

	for (i = 0; i < params->num; i++) {
		vfe_intf = params->entries[i].vfe_intf;
		vfe_mask |= (1 << vfe_intf);
	}

	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 1);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
			__func__, rc);
			goto end;
	}

	if (vfe_mask & (1 << VFE0)) {
		init_completion(&ispif->reset_complete[VFE0]);
		pr_err("%s Init completion VFE0\n", __func__);
			/* initiate reset of ISPIF */
		msm_camera_io_w(0x00001FF9,
				ispif->base + ISPIF_RST_CMD_ADDR);
	}
	if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) {
		init_completion(&ispif->reset_complete[VFE1]);
		pr_err("%s Init completion VFE1\n", __func__);
				msm_camera_io_w(0x00001FF9,
					ispif->base + ISPIF_RST_CMD_1_ADDR);
	}

	if (vfe_mask & (1 << VFE0)) {
		timeout = wait_for_completion_interruptible_timeout(
			&ispif->reset_complete[VFE0], msecs_to_jiffies(500));
		if (timeout <= 0) {
			pr_err("%s: VFE0 reset wait timeout\n", __func__);
			rc = -ETIMEDOUT;
			goto disable_clk;
		}
	}

	if (ispif->hw_num_isps > 1  && (vfe_mask & (1 << VFE1))) {
		timeout = wait_for_completion_interruptible_timeout(
				&ispif->reset_complete[VFE1],
				msecs_to_jiffies(500));
		if (timeout <= 0) {
			pr_err("%s: VFE1 reset wait timeout\n", __func__);
			rc = -ETIMEDOUT;
			goto disable_clk;
		}
	}

	pr_info("%s: ISPIF reset hw done", __func__);
	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
			__func__, rc);
			goto end;
	}


	for (i = 0; i < params->num; i++) {
		intftype = params->entries[i].intftype;
		vfe_intf = params->entries[i].vfe_intf;

		switch (params->entries[0].intftype) {
		case PIX0:
			intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0);
			break;
		case RDI0:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0);
			break;
		case PIX1:
			intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1);
			break;
		case RDI1:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1);
			break;
		case RDI2:
			intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2);
			break;
		default:
			pr_err("%s: invalid intftype=%d\n", __func__,
			params->entries[i].intftype);
			rc = -EPERM;
			goto end;
		}

		msm_ispif_intf_cmd(ispif,
			ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params);
	}

	for (i = 0; i < params->num; i++) {
		intftype = params->entries[i].intftype;

		vfe_intf = params->entries[i].vfe_intf;


		cid_mask = msm_ispif_get_cids_mask_from_cfg(
			&params->entries[i]);

		msm_ispif_enable_intf_cids(ispif, intftype,
			cid_mask, vfe_intf, 1);
	}

end:
	return rc;
disable_clk:
	rc = msm_cam_clk_enable(&ispif->pdev->dev,
		ispif_8974_reset_clk_info, reset_clk,
		ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
	if (rc < 0) {
		pr_err("%s: cannot enable clock, error = %d",
		__func__, rc);
	}

	return -ETIMEDOUT;
}
예제 #21
0
int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
	struct msm_camera_csiphy_params *csiphy_params)
{
	int rc = 0;
	int j = 0;
	uint32_t val = 0;
	uint8_t lane_cnt = 0;
	uint16_t lane_mask = 0;
	void __iomem *csiphybase;
	int i = 0;

	for(i=0; i<8; i++)
		memset(&csiphyErrStatus[i][1], 0, sizeof(uint8_t));
	csiphybase = csiphy_dev->base;
	if (!csiphybase) {
		pr_err("%s: csiphybase NULL\n", __func__);
		return -EINVAL;
	}

	csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask;
	lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id];
	lane_cnt = csiphy_params->lane_cnt;
	if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
		pr_err("%s: unsupported lane cnt %d\n",
			__func__, csiphy_params->lane_cnt);
		return rc;
	}

	CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n",
		__func__,
		csiphy_params->lane_mask,
		csiphy_params->lane_cnt,
		csiphy_params->settle_cnt);
	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
	msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);

	if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
		val = 0x3;
		msm_camera_io_w((lane_mask << 2) | val,
				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
		msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
		msm_camera_io_w(csiphy_params->settle_cnt,
			 csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
		msm_camera_io_w(0x24,
			csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
		msm_camera_io_w(0x24,
			csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR);
	} else {
		val = 0x1;
		msm_camera_io_w((lane_mask << 1) | val,
				csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR);
		msm_camera_io_w(csiphy_params->combo_mode <<
			MIPI_CSIPHY_MODE_CONFIG_SHIFT,
			csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR);
	}

	lane_mask &= 0x1f;
	while (lane_mask & 0x1f) {
		if (!(lane_mask & 0x1)) {
			j++;
			lane_mask >>= 1;
			continue;
		}
		msm_camera_io_w(0x10,
			csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*j);
		msm_camera_io_w(csiphy_params->settle_cnt,
			csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*j);
		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
			MIPI_CSIPHY_INTERRUPT_MASK_ADDR + 0x4*j);
		msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase +
			MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR + 0x4*j);
		j++;
		lane_mask >>= 1;
	}
예제 #22
0
static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
	uint32_t len,
	enum cci_i2c_master_t master,
	enum cci_i2c_queue_t queue)
{
	int32_t rc = 0;
	uint32_t read_val = 0;
	uint32_t reg_offset = master * 0x200 + queue * 0x100;
#if defined(CONFIG_SONY_CAM_QCAMERA)
	uint8_t retry_count = 0;
#endif
	read_val = msm_camera_io_r(cci_dev->base +
		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
	CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d\n",
		__func__, __LINE__, read_val, len,
		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
	if ((read_val + len + 1) > cci_dev->
		cci_i2c_queue_info[master][queue].max_queue_size) {
		uint32_t reg_val = 0;
		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
		CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__);
		msm_camera_io_w(report_val,
			cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
			reg_offset);
		read_val++;
		CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n",
			__func__, __LINE__, read_val);
		msm_camera_io_w(read_val, cci_dev->base +
			CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
		reg_val = 1 << ((master * 2) + queue);
		CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__);
		msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
		CDBG("%s line %d wait_for_completion_interruptible\n",
			__func__, __LINE__);
#if defined(CONFIG_SONY_CAM_QCAMERA)
		retry_count = 4;
		do {
			rc = wait_for_completion_interruptible_timeout(
				&cci_dev->cci_master_info[master].reset_complete
				, CCI_TIMEOUT);
			retry_count--;
			if (rc != -ERESTARTSYS)
				break;
			pr_debug("%s: wait_event interrupted by signal, count = %d",
					__func__, retry_count);
			msleep(20);
		} while (retry_count > 0);
#else
		rc = wait_for_completion_interruptible_timeout(&cci_dev->
			cci_master_info[master].reset_complete, CCI_TIMEOUT);
#endif
		if (rc <= 0) {
			pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
				 __func__, __LINE__);
			if (rc == 0)
				rc = -ETIMEDOUT;
			msm_cci_flush_queue(cci_dev, master);
			return rc;
		}
		rc = cci_dev->cci_master_info[master].status;
		if (rc < 0)
			pr_err("%s failed rc %d\n", __func__, rc);
	}
	return rc;
}
static int msm_ispif_reset(struct ispif_device *ispif)
{
	int rc = 0;
	int i;

	BUG_ON(!ispif);

	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
	for (i = 0; i < ispif->vfe_info.num_vfe; i++) {

		msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT, ispif->base + ISPIF_VFE_m_CTRL_0(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_0(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_1(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_2(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i));

		msm_camera_io_w(0xAAAAAAAA,
			ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));

		msm_camera_io_w(0xAAAAAAAA,
			ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));

		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2));

		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CROP(i, 1));
	}

	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);

	return rc;
}
static int msm_ispif_reset(struct ispif_device *ispif)
{
	int rc = 0;
	int i;

	//                                                                                         

	memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
	for (i = 0; i < ispif->vfe_info.num_vfe; i++) {

		msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT,
			ispif->base + ISPIF_VFE_m_CTRL_0(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i));
		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_0(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_1(i));
		msm_camera_io_w(0xFFFFFFFF, ispif->base +
			ISPIF_VFE_m_IRQ_CLEAR_2(i));

		msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i));

		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
			ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
			ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
		pr_debug("%s: base %x", __func__, (unsigned int)ispif->base);
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
/*                                                                                                       */
#if 0
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2));
#else
        msm_camera_io_w(0, ispif->base +
	        ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0));
        msm_camera_io_w(0, ispif->base +
	        ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1));
        msm_camera_io_w(0, ispif->base +
	        ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 2));
#endif
/*                                                                                                       */
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0));
		msm_camera_io_w(0, ispif->base +
			ISPIF_VFE_m_PIX_INTF_n_CROP(i, 1));
	}

	msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
		ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);

	return rc;
}
static void set_vbif_params(struct msm_jpeg_device *pgmn_dev,
	 void *jpeg_vbif_base)
{
	msm_camera_io_w(0x1,
		jpeg_vbif_base + JPEG_VBIF_CLKON);

	if (pgmn_dev->hw_version != JPEG_8994) {
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF0);
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF1);
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF2);
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF0);
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF1);
		msm_camera_io_w(0x10101010,
			jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF2);
		msm_camera_io_w(0x00001010,
			jpeg_vbif_base + JPEG_VBIF_OUT_RD_LIM_CONF0);
		msm_camera_io_w(0x00000110,
			jpeg_vbif_base + JPEG_VBIF_OUT_WR_LIM_CONF0);
		msm_camera_io_w(0x00000707,
			jpeg_vbif_base + JPEG_VBIF_DDR_OUT_MAX_BURST);
		msm_camera_io_w(0x00000FFF,
			jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO_EN);
		msm_camera_io_w(0x0FFF0FFF,
			jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO);
		msm_camera_io_w(0x2222,
			jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1);
	}

	msm_camera_io_w(0x7,
		jpeg_vbif_base + JPEG_VBIF_OCMEM_OUT_MAX_BURST);
	msm_camera_io_w(0x00000030,
		jpeg_vbif_base + JPEG_VBIF_ARB_CTL);

	/*FE and WE QOS configuration need to be set when
	QOS RR arbitration is enabled*/
	if (pgmn_dev->hw_version != JPEG_8974_V1)
		msm_camera_io_w(0x00000003,
				jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);
	else
		msm_camera_io_w(0x00000001,
				jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB);

	msm_camera_io_w(0x22222222,
		jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0);

}