Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbdd8333 authored by Ramesh V's avatar Ramesh V Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: isp: Support dualcamera overflow



Add support of overflow recovery mechanism
in case of dualcamera.

Change-Id: Ib61358883bc55c519650ebbc049f0cfec1957c0c
Signed-off-by: default avatarRamesh V <ramev@codeaurora.org>
parent 998e5be1
Loading
Loading
Loading
Loading
+133 −12
Original line number Diff line number Diff line
@@ -1187,21 +1187,142 @@ static int msm_ispif_start_frame_boundary(struct ispif_device *ispif,
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif,
	struct msm_ispif_param_data_ext *params)
{
	int rc = 0;
	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;

	rc = msm_ispif_reset_hw(ispif);
	if (!rc)
		rc = msm_ispif_reset(ispif);
	if (!rc)
		rc = msm_ispif_config(ispif, params);
	if (!rc)
		rc = msm_ispif_start_frame_boundary(ispif, 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;
	}

	if (!rc)
		pr_info("ISPIF restart Successful\n");
	else
		pr_info("ISPIF restart Failed\n");
	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_regulators(ispif->vfe_vdd,
					ispif->vfe_vdd_count, 1);
	if (rc < 0)
		return -EFAULT;

	rc = msm_camera_clk_enable(&ispif->pdev->dev,
		ispif->clk_info, ispif->clks,
		ispif->num_clk, 1);
	if (rc < 0)
		goto disable_regulator;

	if (vfe_mask & (1 << VFE0)) {
		atomic_set(&ispif->reset_trig[VFE0], 1);
		/* initiate reset of ISPIF */
		msm_camera_io_w(ISPIF_RST_CMD_MASK_RESTART,
				ispif->base + ISPIF_RST_CMD_ADDR);
		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))) {
		atomic_set(&ispif->reset_trig[VFE1], 1);
		msm_camera_io_w(ISPIF_RST_CMD_1_MASK_RESTART,
			ispif->base + ISPIF_RST_CMD_1_ADDR);
		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_camera_clk_enable(&ispif->pdev->dev,
		ispif->clk_info, ispif->clks,
		ispif->num_clk, 0);
	if (rc < 0)
		goto disable_regulator;

	/* Turn OFF regulators after disabling clocks */
	rc = msm_ispif_set_regulators(ispif->vfe_vdd, ispif->vfe_vdd_count, 0);
	if (rc < 0)
		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_camera_clk_enable(&ispif->pdev->dev,
		ispif->clk_info, ispif->clks,
		ispif->num_clk, 0);
disable_regulator:
	/* Turn OFF regulators */
	msm_ispif_set_regulators(ispif->vfe_vdd, ispif->vfe_vdd_count, 0);
end:
	return rc;
}