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

Commit 83b03f1e authored by Milen Mitkov's avatar Milen Mitkov Committed by Evgeniy Borisov
Browse files

msm: camera: Use adsp_shmem status checks in camera subsys



Take care to synchronize camera hardware and functionality
with the aDSP camera status.

Change-Id: Ia04ae6b714374df5c3a35f5e21037047ad5bd32c
Signed-off-by: default avatarMilen Mitkov <mmitkov@codeaurora.org>
Signed-off-by: default avatarEvgeniy Borisov <gencho@codeaurora.org>
parent 960b9a39
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <media/msm_cam_sensor.h>
#include <media/v4l2-ioctl.h>

#include <media/adsp-shmem-device.h>

#define NO_SET_RATE -1
#define INIT_RATE -2

+12 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "msm_buf_mgr.h"
#include "cam_hw_ops.h"
#include <soc/qcom/cx_ipeak.h>
#include <media/adsp-shmem-device.h>

#define VFE40_8974V1_VERSION 0x10000018
#define VFE40_8974V2_VERSION 0x1001001A
@@ -861,4 +862,15 @@ struct vfe_parent_device {
};
int vfe_hw_probe(struct platform_device *pdev);
void msm_isp_update_last_overflow_ab_ib(struct vfe_device *vfe_dev);

/* Returning true means the VFE is still used from ADSP side */
static inline bool vfe_used_by_adsp(struct vfe_device *vfe_dev)
{
	if (vfe_dev->pdev->id == ADSP_VFE &&
		adsp_shmem_get_state() != CAMERA_STATUS_END)
		return true;

	return false;
}

#endif
+9 −0
Original line number Diff line number Diff line
@@ -305,6 +305,9 @@ static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
	struct msm_vfe_hw_init_parms vbif_parms;
	struct msm_vfe_hw_init_parms ds_parms;

	if (vfe_used_by_adsp(vfe_dev))
		return;

	qos_parms.entries = "qos-entries";
	qos_parms.regs = "qos-regs";
	qos_parms.settings = "qos-settings";
@@ -776,6 +779,9 @@ static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev,
	init_completion(&vfe_dev->reset_complete);
	spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);

	if (vfe_used_by_adsp(vfe_dev))
		return msecs_to_jiffies(50);

	if (first_start) {
		msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
	} else {
@@ -1791,6 +1797,9 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
	struct msm_isp_timestamp ts;
	unsigned long flags;

	if (vfe_used_by_adsp(vfe_dev))
		return msecs_to_jiffies(50);

	/* Keep only halt and restart mask */
	msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
			MSM_ISP_IRQ_SET);
+3 −0
Original line number Diff line number Diff line
@@ -311,6 +311,9 @@ int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
	int rc = -1;
	enum cam_ahb_clk_client id;

	if (vfe_used_by_adsp(vfe_dev))
		return msecs_to_jiffies(50);

	if (vfe_dev->pdev->id == 0)
		id = CAM_AHB_CLIENT_VFE0;
	else
+24 −8
Original line number Diff line number Diff line
@@ -1037,6 +1037,17 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
		break;
	case VIDIOC_MSM_ISP_SMMU_ATTACH:
		mutex_lock(&vfe_dev->core_mutex);
		if (adsp_shmem_get_state() != CAMERA_STATUS_END) {
			pr_debug("Stop adsp camera\n");  /* execute stop cmd */
			wmb(); /* sync memory access with ADSP */
			adsp_shmem_set_state(CAMERA_STATUS_STOP);
			wmb(); /* sync memory access with ADSP */
			usleep_range(1000, 1100);
			rmb(); /* sync memory access with ADSP */
			while (adsp_shmem_get_state() != CAMERA_STATUS_END)
				rmb(); /* sync memory access with ADSP */
		}

		rc = msm_isp_smmu_attach(vfe_dev->buf_mgr, arg);
		mutex_unlock(&vfe_dev->core_mutex);
		break;
@@ -2328,6 +2339,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
	atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);

	if (!vfe_used_by_adsp(vfe_dev))
		vfe_dev->hw_info->vfe_ops.core_ops.clear_status_reg(vfe_dev);

	vfe_dev->vfe_hw_version = msm_camera_io_r(vfe_dev->vfe_base);
@@ -2422,18 +2434,22 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	if (rc <= 0)
		pr_err("%s: halt timeout rc=%ld\n", __func__, rc);

	if (!vfe_used_by_adsp(vfe_dev)) {
		vfe_dev->hw_info->vfe_ops.core_ops.
		update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY);
	}
	vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 0, 0);

	/* put scratch buf in all the wm */
	/* after regular hw stop, reduce open cnt */
	vfe_dev->vfe_open_cnt--;

	if (!vfe_used_by_adsp(vfe_dev)) {
		for (wm = 0; wm < vfe_dev->axi_data.hw_info->num_wm; wm++) {
			msm_isp_cfg_wm_scratch(vfe_dev, wm, VFE_PING_FLAG);
			msm_isp_cfg_wm_scratch(vfe_dev, wm, VFE_PONG_FLAG);
		}
		vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
	/* after regular hw stop, reduce open cnt */
	vfe_dev->vfe_open_cnt--;
	}
	vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr);
	if (vfe_dev->vt_enable) {
		msm_isp_end_avtimer();
Loading