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

Commit 835057fa authored by Venkat Chinta's avatar Venkat Chinta Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: vfe: Add support for CAMIF and VFE TOP



This change adds the register offset structures and
source code changes required to support version 480
VFE TOP and CAMIF hardware in the VFE driver.

Change-Id: I0ee34c207b07c134139a83087cb3e64a50bba468
Signed-off-by: default avatarVishalsingh Hajeri <vhajeri@codeaurora.org>
Signed-off-by: default avatarVenkat Chinta <vchinta@codeaurora.org>
parent d99e192e
Loading
Loading
Loading
Loading
+179 −83
Original line number Diff line number Diff line
@@ -4236,8 +4236,8 @@ static int cam_ife_hw_mgr_get_err_type(
	void                              *handler_priv,
	void                              *payload)
{
	struct cam_isp_resource_node         *hw_res_l = NULL;
	struct cam_isp_resource_node         *hw_res_r = NULL;
	struct cam_isp_resource_node         *hw_res_left = NULL;
	struct cam_isp_resource_node         *hw_res_right = NULL;
	struct cam_ife_hw_mgr_ctx            *ife_hwr_mgr_ctx;
	struct cam_vfe_top_irq_evt_payload   *evt_payload;
	struct cam_ife_hw_mgr_res            *isp_ife_camif_res = NULL;
@@ -4263,40 +4263,41 @@ static int cam_ife_hw_mgr_get_err_type(
			(isp_ife_camif_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF))
			continue;

		hw_res_l = isp_ife_camif_res->hw_res[CAM_ISP_HW_SPLIT_LEFT];
		hw_res_r = isp_ife_camif_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT];
		hw_res_left = isp_ife_camif_res->hw_res[CAM_ISP_HW_SPLIT_LEFT];
		hw_res_right =
			isp_ife_camif_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT];

		CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d\n",
		CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d",
			isp_ife_camif_res->is_dual_vfe);

		/* ERROR check for Left VFE */
		if (!hw_res_l) {
		if (!hw_res_left) {
			CAM_DBG(CAM_ISP, "VFE(L) Device is NULL");
			break;
		}

		CAM_DBG(CAM_ISP, "core id= %d, HW id %d", core_idx,
			hw_res_l->hw_intf->hw_idx);
			hw_res_left->hw_intf->hw_idx);

		if (core_idx == hw_res_l->hw_intf->hw_idx) {
			status = hw_res_l->bottom_half_handler(
				hw_res_l, evt_payload);
		if (core_idx == hw_res_left->hw_intf->hw_idx) {
			status = hw_res_left->bottom_half_handler(
				hw_res_left, evt_payload);
		}

		if (status)
			break;

		/* ERROR check for Right  VFE */
		if (!hw_res_r) {
		if (!hw_res_right) {
			CAM_DBG(CAM_ISP, "VFE(R) Device is NULL");
			continue;
		}
		CAM_DBG(CAM_ISP, "core id= %d, HW id %d", core_idx,
			hw_res_r->hw_intf->hw_idx);
			hw_res_right->hw_intf->hw_idx);

		if (core_idx == hw_res_r->hw_intf->hw_idx) {
			status = hw_res_r->bottom_half_handler(
				hw_res_r, evt_payload);
		if (core_idx == hw_res_right->hw_intf->hw_idx) {
			status = hw_res_right->bottom_half_handler(
				hw_res_right, evt_payload);
		}

		if (status)
@@ -4492,6 +4493,62 @@ static int cam_ife_hw_mgr_handle_reg_update(
	return 0;
}

static int cam_ife_hw_mgr_handle_reg_update_in_bus(
	void                              *handler_priv,
	void                              *payload)
{
	struct cam_ife_hw_mgr_ctx               *ife_hwr_mgr_ctx;
	struct cam_vfe_bus_irq_evt_payload      *evt_payload;
	cam_hw_event_cb_func                     ife_hwr_irq_rup_cb;
	struct cam_isp_hw_reg_update_event_data  rup_event_data;
	uint32_t                                 core_idx;
	struct cam_ife_hw_mgr_res               *isp_ife_out_res;
	struct cam_isp_resource_node            *hw_res_left;
	uint32_t                                 rup_status = -EINVAL;
	int                                      i = 0;

	CAM_DBG(CAM_ISP, "Enter");

	ife_hwr_mgr_ctx = handler_priv;
	evt_payload = payload;

	if (!handler_priv || !payload) {
		CAM_ERR(CAM_ISP, "Invalid Parameter");
		return -EPERM;
	}

	core_idx = evt_payload->core_index;
	ife_hwr_irq_rup_cb =
		ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE];

	evt_payload->evt_id = CAM_ISP_HW_EVENT_REG_UPDATE;
	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
		isp_ife_out_res = &ife_hwr_mgr_ctx->res_list_ife_out[i];
		if (isp_ife_out_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
			continue;

		hw_res_left = isp_ife_out_res->hw_res[0];
		if (hw_res_left && (evt_payload->core_index ==
			hw_res_left->hw_intf->hw_idx))
			rup_status = hw_res_left->bottom_half_handler(
				hw_res_left, evt_payload);
	}

	CAM_DBG(CAM_ISP, "Exit rup_status = %d", rup_status);

	if (!rup_status) {
		CAM_DBG(CAM_ISP, "Exit rup_status = %d", rup_status);

	if (!atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
		ife_hwr_irq_rup_cb(
			ife_hwr_mgr_ctx->common.cb_priv,
				CAM_ISP_HW_EVENT_REG_UPDATE,
				&rup_event_data);
	}

	return 0;
}

static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
	struct cam_ife_hw_mgr_ctx   *ife_hw_mgr_ctx,
	uint32_t                     core_idx0,
@@ -4548,8 +4605,8 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
	void                              *payload)
{
	int32_t rc = -EINVAL;
	struct cam_isp_resource_node         *hw_res_l;
	struct cam_isp_resource_node         *hw_res_r;
	struct cam_isp_resource_node         *hw_res_left;
	struct cam_isp_resource_node         *hw_res_right;
	struct cam_ife_hw_mgr_ctx            *ife_hwr_mgr_ctx;
	struct cam_vfe_top_irq_evt_payload   *evt_payload;
	struct cam_ife_hw_mgr_res            *isp_ife_camif_res = NULL;
@@ -4578,21 +4635,21 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
			continue;
		}

		hw_res_l = isp_ife_camif_res->hw_res[0];
		hw_res_r = isp_ife_camif_res->hw_res[1];
		hw_res_left = isp_ife_camif_res->hw_res[0];
		hw_res_right = isp_ife_camif_res->hw_res[1];

		switch (isp_ife_camif_res->is_dual_vfe) {
		/* Handling Single VFE Scenario */
		case 0:
			/* EPOCH check for Left side VFE */
			if (!hw_res_l) {
			if (!hw_res_left) {
				CAM_ERR(CAM_ISP, "Left Device is NULL");
				break;
			}

			if (core_idx == hw_res_l->hw_intf->hw_idx) {
				epoch_status = hw_res_l->bottom_half_handler(
					hw_res_l, evt_payload);
			if (core_idx == hw_res_left->hw_intf->hw_idx) {
				epoch_status = hw_res_left->bottom_half_handler(
					hw_res_left, evt_payload);
				if (atomic_read(
					&ife_hwr_mgr_ctx->overflow_pending))
					break;
@@ -4609,13 +4666,13 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
		case 1:
			/* SOF check for Left side VFE (Master)*/

			if ((!hw_res_l) || (!hw_res_r)) {
			if ((!hw_res_left) || (!hw_res_right)) {
				CAM_ERR(CAM_ISP, "Dual VFE Device is NULL");
				break;
			}
			if (core_idx == hw_res_l->hw_intf->hw_idx) {
				epoch_status = hw_res_l->bottom_half_handler(
					hw_res_l, evt_payload);
			if (core_idx == hw_res_left->hw_intf->hw_idx) {
				epoch_status = hw_res_left->bottom_half_handler(
					hw_res_left, evt_payload);

				if (!epoch_status)
					ife_hwr_mgr_ctx->epoch_cnt[core_idx]++;
@@ -4624,9 +4681,10 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
			}

			/* SOF check for Right side VFE */
			if (core_idx == hw_res_r->hw_intf->hw_idx) {
				epoch_status = hw_res_r->bottom_half_handler(
					hw_res_r, evt_payload);
			if (core_idx == hw_res_right->hw_intf->hw_idx) {
				epoch_status =
					hw_res_right->bottom_half_handler(
					hw_res_right, evt_payload);

				if (!epoch_status)
					ife_hwr_mgr_ctx->epoch_cnt[core_idx]++;
@@ -4634,8 +4692,8 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
					break;
			}

			core_index0 = hw_res_l->hw_intf->hw_idx;
			core_index1 = hw_res_r->hw_intf->hw_idx;
			core_index0 = hw_res_left->hw_intf->hw_idx;
			core_index1 = hw_res_right->hw_intf->hw_idx;

			rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(
					ife_hwr_mgr_ctx,
@@ -4671,8 +4729,8 @@ static int cam_ife_hw_mgr_process_camif_sof(
	struct cam_ife_hw_mgr_ctx            *ife_hwr_mgr_ctx,
	struct cam_vfe_top_irq_evt_payload   *evt_payload)
{
	struct cam_isp_resource_node         *hw_res_l = NULL;
	struct cam_isp_resource_node         *hw_res_r = NULL;
	struct cam_isp_resource_node         *hw_res_left = NULL;
	struct cam_isp_resource_node         *hw_res_right = NULL;
	int32_t rc = -EINVAL;
	uint32_t  core_idx;
	uint32_t  sof_status = 0;
@@ -4681,8 +4739,8 @@ static int cam_ife_hw_mgr_process_camif_sof(

	CAM_DBG(CAM_ISP, "Enter");
	core_idx = evt_payload->core_index;
	hw_res_l = isp_ife_camif_res->hw_res[0];
	hw_res_r = isp_ife_camif_res->hw_res[1];
	hw_res_left = isp_ife_camif_res->hw_res[0];
	hw_res_right = isp_ife_camif_res->hw_res[1];
	CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d",
		isp_ife_camif_res->is_dual_vfe);

@@ -4690,16 +4748,16 @@ static int cam_ife_hw_mgr_process_camif_sof(
	/* Handling Single VFE Scenario */
	case 0:
		/* SOF check for Left side VFE */
		if (!hw_res_l) {
		if (!hw_res_left) {
			CAM_ERR(CAM_ISP, "VFE Device is NULL");
			break;
		}
		CAM_DBG(CAM_ISP, "curr_core_idx = %d,core idx hw = %d",
			core_idx, hw_res_l->hw_intf->hw_idx);
			core_idx, hw_res_left->hw_intf->hw_idx);

		if (core_idx == hw_res_l->hw_intf->hw_idx) {
			sof_status = hw_res_l->bottom_half_handler(hw_res_l,
				evt_payload);
		if (core_idx == hw_res_left->hw_intf->hw_idx) {
			sof_status = hw_res_left->bottom_half_handler(
				hw_res_left, evt_payload);
			if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
				break;
			if (!sof_status)
@@ -4712,17 +4770,17 @@ static int cam_ife_hw_mgr_process_camif_sof(
	case 1:
		/* SOF check for Left side VFE */

		if (!hw_res_l) {
		if (!hw_res_left) {
			CAM_ERR(CAM_ISP, "VFE Device is NULL");
			break;
		}
		CAM_DBG(CAM_ISP, "curr_core_idx = %d, res hw idx= %d",
				 core_idx,
				hw_res_l->hw_intf->hw_idx);
				hw_res_left->hw_intf->hw_idx);

		if (core_idx == hw_res_l->hw_intf->hw_idx) {
			sof_status = hw_res_l->bottom_half_handler(
				hw_res_l, evt_payload);
		if (core_idx == hw_res_left->hw_intf->hw_idx) {
			sof_status = hw_res_left->bottom_half_handler(
				hw_res_left, evt_payload);
			if (!sof_status)
				ife_hwr_mgr_ctx->sof_cnt[core_idx]++;
			else
@@ -4730,24 +4788,24 @@ static int cam_ife_hw_mgr_process_camif_sof(
		}

		/* SOF check for Right side VFE */
		if (!hw_res_r) {
		if (!hw_res_right) {
			CAM_ERR(CAM_ISP, "VFE Device is NULL");
			break;
		}
		CAM_DBG(CAM_ISP, "curr_core_idx = %d, ews hw idx= %d",
				 core_idx,
				hw_res_r->hw_intf->hw_idx);
		if (core_idx == hw_res_r->hw_intf->hw_idx) {
			sof_status = hw_res_r->bottom_half_handler(hw_res_r,
				evt_payload);
				hw_res_right->hw_intf->hw_idx);
		if (core_idx == hw_res_right->hw_intf->hw_idx) {
			sof_status = hw_res_right->bottom_half_handler(
				hw_res_right, evt_payload);
			if (!sof_status)
				ife_hwr_mgr_ctx->sof_cnt[core_idx]++;
			else
				break;
		}

		core_index0 = hw_res_l->hw_intf->hw_idx;
		core_index1 = hw_res_r->hw_intf->hw_idx;
		core_index0 = hw_res_left->hw_intf->hw_idx;
		core_index1 = hw_res_right->hw_intf->hw_idx;

		if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
			break;
@@ -4867,8 +4925,8 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
	void                              *payload)
{
	int32_t rc = -EINVAL;
	struct cam_isp_resource_node         *hw_res_l = NULL;
	struct cam_isp_resource_node         *hw_res_r = NULL;
	struct cam_isp_resource_node         *hw_res_left = NULL;
	struct cam_isp_resource_node         *hw_res_right = NULL;
	struct cam_ife_hw_mgr_ctx            *ife_hwr_mgr_ctx;
	struct cam_vfe_top_irq_evt_payload   *evt_payload;
	struct cam_ife_hw_mgr_res            *isp_ife_camif_res = NULL;
@@ -4901,8 +4959,8 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
			(isp_ife_camif_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF))
			continue;

		hw_res_l = isp_ife_camif_res->hw_res[0];
		hw_res_r = isp_ife_camif_res->hw_res[1];
		hw_res_left = isp_ife_camif_res->hw_res[0];
		hw_res_right = isp_ife_camif_res->hw_res[1];

		CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d",
				isp_ife_camif_res->is_dual_vfe);
@@ -4910,17 +4968,17 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
		/* Handling Single VFE Scenario */
		case 0:
			/* EOF check for Left side VFE */
			if (!hw_res_l) {
			if (!hw_res_left) {
				pr_err("%s: VFE Device is NULL\n",
					__func__);
				break;
			}
			CAM_DBG(CAM_ISP, "curr_core_idx = %d, core idx hw = %d",
					core_idx, hw_res_l->hw_intf->hw_idx);
					core_idx, hw_res_left->hw_intf->hw_idx);

			if (core_idx == hw_res_l->hw_intf->hw_idx) {
				eof_status = hw_res_l->bottom_half_handler(
					hw_res_l, evt_payload);
			if (core_idx == hw_res_left->hw_intf->hw_idx) {
				eof_status = hw_res_left->bottom_half_handler(
					hw_res_left, evt_payload);
				if (atomic_read(
					&ife_hwr_mgr_ctx->overflow_pending))
					break;
@@ -4934,13 +4992,13 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
			break;
		/* Handling dual VFE Scenario */
		case 1:
			if ((!hw_res_l) || (!hw_res_r)) {
			if ((!hw_res_left) || (!hw_res_right)) {
				CAM_ERR(CAM_ISP, "Dual VFE Device is NULL");
				break;
			}
			if (core_idx == hw_res_l->hw_intf->hw_idx) {
				eof_status = hw_res_l->bottom_half_handler(
					hw_res_l, evt_payload);
			if (core_idx == hw_res_left->hw_intf->hw_idx) {
				eof_status = hw_res_left->bottom_half_handler(
					hw_res_left, evt_payload);

				if (!eof_status)
					ife_hwr_mgr_ctx->eof_cnt[core_idx]++;
@@ -4949,9 +5007,9 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
			}

			/* EOF check for Right side VFE */
			if (core_idx == hw_res_r->hw_intf->hw_idx) {
				eof_status = hw_res_r->bottom_half_handler(
					hw_res_r, evt_payload);
			if (core_idx == hw_res_right->hw_intf->hw_idx) {
				eof_status = hw_res_right->bottom_half_handler(
					hw_res_right, evt_payload);

				if (!eof_status)
					ife_hwr_mgr_ctx->eof_cnt[core_idx]++;
@@ -4959,8 +5017,8 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
					break;
			}

			core_index0 = hw_res_l->hw_intf->hw_idx;
			core_index1 = hw_res_r->hw_intf->hw_idx;
			core_index0 = hw_res_left->hw_intf->hw_idx;
			core_index1 = hw_res_right->hw_intf->hw_idx;

			rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(
					ife_hwr_mgr_ctx,
@@ -4999,7 +5057,7 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
	int32_t                              i;
	int32_t                              rc = 0;
	cam_hw_event_cb_func                 ife_hwr_irq_wm_done_cb;
	struct cam_isp_resource_node        *hw_res_l = NULL;
	struct cam_isp_resource_node        *hw_res_left = NULL;
	struct cam_ife_hw_mgr_ctx           *ife_hwr_mgr_ctx = NULL;
	struct cam_vfe_bus_irq_evt_payload  *evt_payload = payload;
	struct cam_ife_hw_mgr_res           *isp_ife_out_res = NULL;
@@ -5023,7 +5081,7 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
		if (isp_ife_out_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
			continue;

		hw_res_l = isp_ife_out_res->hw_res[0];
		hw_res_left = isp_ife_out_res->hw_res[0];

		/*
		 * DUAL VFE: Index 0 is always a master. In case of composite
@@ -5032,10 +5090,10 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
		 * Index zero is valid
		 */

		if (hw_res_l && (evt_payload->core_index ==
			hw_res_l->hw_intf->hw_idx))
			buf_done_status = hw_res_l->bottom_half_handler(
				hw_res_l, evt_payload);
		if (hw_res_left && (evt_payload->core_index ==
			hw_res_left->hw_intf->hw_idx))
			buf_done_status = hw_res_left->bottom_half_handler(
				hw_res_left, evt_payload);
		else
			continue;

@@ -5166,9 +5224,10 @@ int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv)
	CAM_DBG(CAM_ISP, "addr of evt_payload = %pK core_index:%d",
		(void *)evt_payload,
		evt_payload->core_index);
	CAM_DBG(CAM_ISP, "irq_status_0: = %x", evt_payload->irq_reg_val[0]);
	CAM_DBG(CAM_ISP, "irq_status_1: = %x", evt_payload->irq_reg_val[1]);
	CAM_DBG(CAM_ISP, "Violation register: = %x",
	CAM_DBG(CAM_ISP,
		"irq_status_0 = 0x%x, irq_status_1 = 0x%x, irq_status_2 = 0x%x ",
		evt_payload->irq_reg_val[0],
		evt_payload->irq_reg_val[1],
		evt_payload->irq_reg_val[2]);

	/*
@@ -5195,10 +5254,12 @@ int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv)
	cam_ife_hw_mgr_handle_sof(ife_hwr_mgr_ctx,
		evt_payload_priv);

	if (evt_payload->hw_version != CAM_CPAS_TITAN_480_V100) {
		CAM_DBG(CAM_ISP, "Calling RUP");
		/* REG UPDATE */
		cam_ife_hw_mgr_handle_reg_update(ife_hwr_mgr_ctx,
		evt_payload_priv);
	}

	CAM_DBG(CAM_ISP, "Calling EPOCH");
	/* EPOCH IRQ */
@@ -5210,6 +5271,41 @@ int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv)
	return IRQ_HANDLED;
}


int cam_ife_mgr_do_tasklet_reg_update(
	void *handler_priv, void *evt_payload_priv)
{
	struct cam_ife_hw_mgr_ctx            *ife_hwr_mgr_ctx = handler_priv;
	struct cam_vfe_bus_irq_evt_payload   *evt_payload;
	int                                   rc = -EINVAL;

	evt_payload = evt_payload_priv;

	if (!evt_payload_priv || !handler_priv) {
		CAM_ERR(CAM_ISP, "Invalid handle:%pK or event payload:%pK",
			handler_priv, evt_payload_priv);
		return rc;
	}
	ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)handler_priv;

	CAM_DBG(CAM_ISP, "addr of evt_payload = %pK core_index:%d",
		(void *)evt_payload,
		evt_payload->core_index);
	CAM_DBG(CAM_ISP,
		"bus_irq_status_0: = 0x%x, bus_irq_status_1: = 0x%x, calling RUP",
		evt_payload->irq_reg_val[0],
		evt_payload->irq_reg_val[1]);
	/* REG UPDATE */
	rc = cam_ife_hw_mgr_handle_reg_update_in_bus(ife_hwr_mgr_ctx,
		evt_payload_priv);

	if (rc)
		CAM_ERR(CAM_ISP,
			"Encountered Error, rc = %d", rc);

	return rc;
}

static int cam_ife_hw_mgr_sort_dev_with_caps(
	struct cam_ife_hw_mgr *ife_hw_mgr)
{
+13 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_IFE_HW_MGR_H_
@@ -232,4 +232,16 @@ int cam_ife_mgr_do_tasklet_buf_done(void *handler_priv, void *evt_payload_priv);
 */
int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv);

/**
 * cam_ife_mgr_do_tasklet_reg_update()
 *
 * @brief:              Tasklet handle function for reg update
 *
 * @handler_priv:       Tasklet information handle
 * @evt_payload_priv:   Event payload for the handler funciton
 *
 */
int cam_ife_mgr_do_tasklet_reg_update(void *handler_priv,
	void *evt_payload_priv);

#endif /* _CAM_IFE_HW_MGR_H_ */
+6 −1
Original line number Diff line number Diff line
@@ -52,7 +52,8 @@ enum cam_vfe_hw_irq_status {
enum cam_vfe_hw_irq_regs {
	CAM_IFE_IRQ_CAMIF_REG_STATUS0           = 0,
	CAM_IFE_IRQ_CAMIF_REG_STATUS1           = 1,
	CAM_IFE_IRQ_VIOLATION_STATUS            = 2,
	CAM_IFE_IRQ_CAMIF_REG_STATUS2           = 2,
	CAM_IFE_IRQ_VIOLATION_STATUS            = 3,
	CAM_IFE_IRQ_REGISTERS_MAX,
};

@@ -232,6 +233,7 @@ struct cam_vfe_bw_control_args {
 *                           handled
 * @error_type:              Identify different errors
 * @ts:                      Timestamp
 * @hw_version:              CPAS hw version
 */
struct cam_vfe_top_irq_evt_payload {
	struct list_head           list;
@@ -241,6 +243,7 @@ struct cam_vfe_top_irq_evt_payload {
	uint32_t                   irq_reg_val[CAM_IFE_IRQ_REGISTERS_MAX];
	uint32_t                   error_type;
	struct cam_isp_timestamp   ts;
	uint32_t                   hw_version;
};

/*
@@ -285,12 +288,14 @@ struct cam_vfe_bus_irq_evt_payload {
 * @mem_base:                Mapped base address of the register space
 * @reset_complete:          Completion structure to be signaled if Reset IRQ
 *                           is Set
 * @hw_version:              CPAS hw version
 */
struct cam_vfe_irq_handler_priv {
	uint32_t                     core_index;
	void                        *core_info;
	void __iomem                *mem_base;
	struct completion           *reset_complete;
	uint32_t                     hw_version;
};

/*
+62 −36
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/delay.h>
@@ -16,16 +16,19 @@
#include "cam_vfe_top.h"
#include "cam_ife_hw_mgr.h"
#include "cam_debug_util.h"
#include "cam_cpas_api.h"

static const char drv_name[] = "vfe";
static uint32_t irq_reg_offset[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x0000006C,
	0x00000070,
	0x0000007C,
	0x00000054,
	0x00000058,
	0x0000005C,
	0x00000074,
};

static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x00000017,
	0x00000000,
	0x00000007,
	0x00000000,
};

@@ -35,12 +38,14 @@ static uint32_t camif_fe_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
};

static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x0003FC00,
	0xEFFF7EBC,
	0xFBE00200,
	0x00000000,
	0x303FFF80,
};

static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x780001e0,
	0x38E00000,
	0xFFF00000,
	0x00000000,
};

@@ -126,22 +131,35 @@ int cam_vfe_reset_irq_top_half(uint32_t evt_id,
	handler_priv = th_payload->handler_priv;

	CAM_DBG(CAM_ISP, "Enter");
	CAM_DBG(CAM_ISP, "IRQ status_0 = 0x%x", th_payload->evt_status_arr[0]);

	if (th_payload->evt_status_arr[0] & (1<<31)) {
	/*
	 * Clear All IRQs to avoid spurious IRQs immediately
	 * after Reset Done.
	 */

	switch (handler_priv->hw_version) {
	case CAM_CPAS_TITAN_480_V100:
		if (th_payload->evt_status_arr[0] & 0x1) {
			cam_io_w(0xFFFFFFFF, handler_priv->mem_base + 0x48);
			cam_io_w(0xFFFFFFFF, handler_priv->mem_base + 0x4C);
			cam_io_w(0xFFFFFFFF, handler_priv->mem_base + 0x50);
			cam_io_w(0x1, handler_priv->mem_base + 0x38);
			CAM_DBG(CAM_ISP, "Calling Complete for RESET CMD");
			complete(handler_priv->reset_complete);
			rc = 0;
		}
		break;
	default:
		if (th_payload->evt_status_arr[0] & (1<<31)) {
			cam_io_w(0xFFFFFFFF, handler_priv->mem_base + 0x64);
			cam_io_w(0xFFFFFFFF, handler_priv->mem_base + 0x68);
		cam_io_w(0x1, handler_priv->mem_base + 0x58);
			cam_io_w(0x00000001, handler_priv->mem_base + 0x58);
			CAM_DBG(CAM_ISP, "Calling Complete for RESET CMD");
			complete(handler_priv->reset_complete);


			rc = 0;
		}
		break;
	}

	CAM_DBG(CAM_ISP, "Exit");
	return rc;
@@ -396,6 +414,7 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
	core_info->irq_payload.core_index = soc_info->index;
	core_info->irq_payload.mem_base =
		vfe_hw->soc_info.reg_map[VFE_CORE_BASE_IDX].mem_base;
	core_info->irq_payload.hw_version = soc_info->hw_version;
	core_info->irq_payload.core_info = core_info;
	core_info->irq_payload.reset_complete = &vfe_hw->hw_complete;

@@ -450,8 +469,10 @@ static int cam_vfe_irq_top_half(uint32_t evt_id,

	handler_priv = th_payload->handler_priv;

	CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
	CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
	for (i = 0; i < th_payload->num_registers; i++)
		CAM_DBG(CAM_ISP, "IRQ status_%d = 0x%x",
		i, th_payload->evt_status_arr[i]);


	rc  = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
	if (rc) {
@@ -469,15 +490,16 @@ static int cam_vfe_irq_top_half(uint32_t evt_id,
	evt_payload->core_index = handler_priv->core_index;
	evt_payload->core_info  = handler_priv->core_info;
	evt_payload->evt_id  = evt_id;
	evt_payload->hw_version = handler_priv->hw_version;

	for (i = 0; i < th_payload->num_registers; i++)
		evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];

	for (; i < CAM_IFE_IRQ_REGISTERS_MAX; i++) {
	evt_payload->irq_reg_val[i] = cam_io_r(handler_priv->mem_base +
		irq_reg_offset[i]);
	}
	CAM_DBG(CAM_ISP, "Violation status = %x", evt_payload->irq_reg_val[2]);

	CAM_DBG(CAM_ISP,
		"Violation status = 0x%x", evt_payload->irq_reg_val[i]);

	th_payload->evt_payload_priv = evt_payload;

@@ -572,6 +594,7 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size)
	struct cam_vfe_hw_core_info       *core_info = NULL;
	struct cam_hw_info                *vfe_hw  = hw_priv;
	struct cam_isp_resource_node      *isp_res;
	struct cam_hw_soc_info            *soc_info = NULL;
	int                                rc = 0;

	if (!hw_priv || !start_args ||
@@ -580,9 +603,11 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size)
		return -EINVAL;
	}

	soc_info = &vfe_hw->soc_info;
	core_info = (struct cam_vfe_hw_core_info *)vfe_hw->core_info;
	isp_res = (struct cam_isp_resource_node  *)start_args;
	core_info->tasklet_info = isp_res->tasklet_info;
	core_info->irq_payload.hw_version = soc_info->hw_version;

	mutex_lock(&vfe_hw->hw_mutex);
	if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN) {
@@ -823,7 +848,8 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info *core_info,
		CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX),
		vfe_hw_info->irq_reg_info, &core_info->vfe_irq_controller);
	if (rc) {
		CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
		CAM_ERR(CAM_ISP,
			"Error, cam_irq_controller_init failed rc = %d", rc);
		return rc;
	}

@@ -831,7 +857,7 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info *core_info,
		soc_info, hw_intf, vfe_hw_info->top_hw_info,
		&core_info->vfe_top);
	if (rc) {
		CAM_ERR(CAM_ISP, "Error! cam_vfe_top_init failed");
		CAM_ERR(CAM_ISP, "Error, cam_vfe_top_init failed rc = %d", rc);
		goto deinit_controller;
	}

@@ -840,7 +866,7 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info *core_info,
		vfe_hw_info->bus_hw_info, core_info->vfe_irq_controller,
		&core_info->vfe_bus);
	if (rc) {
		CAM_ERR(CAM_ISP, "Error! cam_vfe_bus_init failed");
		CAM_ERR(CAM_ISP, "Error, cam_vfe_bus_init failed rc = %d", rc);
		goto deinit_top;
	}

@@ -850,7 +876,7 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info *core_info,
			soc_info, hw_intf, vfe_hw_info->bus_rd_hw_info,
			core_info->vfe_irq_controller, &core_info->vfe_rd_bus);
		if (rc) {
			CAM_ERR(CAM_ISP, "Error! RD cam_vfe_bus_init failed");
			CAM_WARN(CAM_ISP, "Error, RD cam_vfe_bus_init failed");
			rc = 0;
		}
		CAM_DBG(CAM_ISP, "vfe_bus_rd %pK hw_idx %d",
+1 −1
Original line number Diff line number Diff line
@@ -13,4 +13,4 @@ ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_h
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw

obj-$(CONFIG_SPECTRA_CAMERA) += cam_vfe17x.o
obj-$(CONFIG_SPECTRA_CAMERA) += cam_vfe.o
Loading