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

Commit 5a983fec authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 125d16b7 835057fa
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