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

Commit 19f55813 authored by Harsh Shah's avatar Harsh Shah Committed by Soundrapandian Jeyaprakash
Browse files

msm: camera: isp: Add support for BUS IRQ controller



Initialize BUS IRQ controller. Remove hard code subscribe of IRQ mask
and add independent subscribe/unsubscribe for each WM/composite_group.

Change-Id: I02983ae9811c33ec353b2d1caecbd5c84f7177ae
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
Signed-off-by: default avatarSoundrapandian Jeyaprakash <jsoundra@codeaurora.org>
parent 545df9a2
Loading
Loading
Loading
Loading
+16 −24
Original line number Diff line number Diff line
@@ -489,6 +489,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi(
			continue;

		vfe_acquire.vfe_out.cdm_ops = ife_ctx->cdm_ops;
		vfe_acquire.vfe_out.ctx = ife_ctx;
		vfe_acquire.vfe_out.out_port_info = out_port;
		vfe_acquire.vfe_out.split_id = CAM_ISP_HW_SPLIT_LEFT;
		vfe_acquire.vfe_out.unique_id = ife_ctx->ctx_index;
@@ -552,6 +553,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
		vfe_acquire.rsrc_type = CAM_ISP_RESOURCE_VFE_OUT;
		vfe_acquire.tasklet = ife_ctx->common.tasklet_info;
		vfe_acquire.vfe_out.cdm_ops = ife_ctx->cdm_ops;
		vfe_acquire.vfe_out.ctx = ife_ctx;
		vfe_acquire.vfe_out.out_port_info =  out_port;
		vfe_acquire.vfe_out.is_dual       = ife_src_res->is_dual_vfe;
		vfe_acquire.vfe_out.unique_id     = ife_ctx->ctx_index;
@@ -1334,7 +1336,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
		return -EPERM;
	}

	CDBG("%s%d: Enter...ctx id:%d\n", __func__, __LINE__, ctx->ctx_index);
	CDBG("%s:%d Enter ctx id:%d\n", __func__, __LINE__, ctx->ctx_index);

	if (cfg->num_hw_update_entries > 0) {
		cdm_cmd = ctx->cdm_cmd;
@@ -2326,7 +2328,9 @@ static int cam_ife_hw_mgr_handle_rup_for_camif_hw_res(

	}

	CDBG("%s: Exit (rup_status = %d)!\n", __func__, rup_status);
	if (!rup_status)
		CDBG("%s: Exit rup_status = %d\n", __func__, rup_status);

	return 0;
}

@@ -2470,7 +2474,9 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(
		}
	}

	CDBG("%s: Exit (epoch_status = %d)!\n", __func__, epoch_status);
	if (!epoch_status)
		CDBG("%s: Exit epoch_status = %d\n", __func__, epoch_status);

	return 0;
}

@@ -2640,11 +2646,11 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(

{
	int32_t                              buf_done_status = 0;
	int32_t                              i = 0;
	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_ife_hw_mgr_ctx           *ife_hwr_mgr_ctx = handler_priv;
	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;
	struct cam_hw_event_recovery_data    recovery_data;
@@ -2655,6 +2661,7 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(

	CDBG("%s:Enter\n", __func__);

	ife_hwr_mgr_ctx = evt_payload->ctx;
	ife_hwr_irq_wm_done_cb =
		ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE];

@@ -2734,13 +2741,11 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
			}
			break;
		}
		CDBG("%s:buf_done status:(%d),isp_ife_out_res->res_id : 0x%x\n",
			__func__, buf_done_status, isp_ife_out_res->res_id);
		if (!buf_done_status)
			CDBG("buf_done status:(%d),out_res->res_id: 0x%x\n",
			buf_done_status, isp_ife_out_res->res_id);
	}


	CDBG("%s: Exit (buf_done_status (Success) = %d)!\n", __func__,
			buf_done_status);
	return rc;

err:
@@ -2775,7 +2780,7 @@ int cam_ife_mgr_do_tasklet_buf_done(void *handler_priv,
		return rc;

	evt_payload = evt_payload_priv;
	ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)handler_priv;
	ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)evt_payload->ctx;

	CDBG("addr of evt_payload = %llx\n", (uint64_t)evt_payload);
	CDBG("bus_irq_status_0: = %x\n", evt_payload->irq_reg_val[0]);
@@ -2786,19 +2791,6 @@ int cam_ife_mgr_do_tasklet_buf_done(void *handler_priv,
	CDBG("bus_irq_dual_comp_err: = %x\n", evt_payload->irq_reg_val[5]);
	CDBG("bus_irq_dual_comp_owrt: = %x\n", evt_payload->irq_reg_val[6]);

	/*
	 * If overflow/overwrite/error/violation are pending
	 * for this context it needs to be handled remaining
	 * interrupts are ignored.
	 */
	rc = cam_ife_hw_mgr_handle_camif_error(ife_hwr_mgr_ctx,
		evt_payload_priv);
	if (rc) {
		pr_err("%s: Encountered Error (%d), ignoring other irqs\n",
			__func__, rc);
		return IRQ_HANDLED;
	}

	CDBG("%s: Calling Buf_done\n", __func__);
	/* WM Done */
	return cam_ife_hw_mgr_handle_buf_done_for_hw_res(ife_hwr_mgr_ctx,
+10 −10
Original line number Diff line number Diff line
@@ -271,14 +271,6 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
		return -EINVAL;
	}

	if (sizeof(evt_bit_mask_arr) !=
		sizeof(uint32_t) * controller->num_registers) {
		pr_err("Invalid evt_mask size = %lu expected = %lu\n",
			sizeof(evt_bit_mask_arr),
			sizeof(uint32_t) * controller->num_registers);
		return -EINVAL;
	}

	evt_handler = kzalloc(sizeof(struct cam_irq_evt_handler), GFP_KERNEL);
	if (!evt_handler) {
		CDBG("Error allocating hlist_node\n");
@@ -306,6 +298,8 @@ int cam_irq_controller_subscribe_irq(void *irq_controller,
	evt_handler->bottom_half              = bottom_half;
	evt_handler->bottom_half_enqueue_func = bottom_half_enqueue_func;
	evt_handler->index                    = controller->hdl_idx++;

	/* Avoid rollover to negative values */
	if (controller->hdl_idx > 0x3FFFFFFF)
		controller->hdl_idx = 1;

@@ -468,7 +462,8 @@ static void cam_irq_controller_th_processing(
				(void *)th_payload);

		if (!rc && evt_handler->bottom_half_handler) {
			CDBG("Enqueuing bottom half\n");
			CDBG("Enqueuing bottom half for %s\n",
				controller->name);
			if (evt_handler->bottom_half_enqueue_func) {
				evt_handler->bottom_half_enqueue_func(
					evt_handler->bottom_half,
@@ -492,6 +487,8 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
	if (!controller)
		return IRQ_NONE;

	CDBG("locking controller %pK name %s rw_lock %pK\n",
		controller, controller->name, &controller->rw_lock);
	read_lock(&controller->rw_lock);
	for (i = 0; i < controller->num_registers; i++) {
		controller->irq_status_arr[i] = cam_io_r_mb(
@@ -500,7 +497,8 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
		cam_io_w_mb(controller->irq_status_arr[i],
			controller->mem_base +
			controller->irq_register_arr[i].clear_reg_offset);
		CDBG("Read irq status%d = 0x%x\n", i,
		CDBG("Read irq status%d (0x%x) = 0x%x\n", i,
			controller->irq_register_arr[i].status_reg_offset,
			controller->irq_status_arr[i]);
		for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
			if (controller->irq_register_arr[i].
@@ -512,6 +510,8 @@ irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
		}
	}
	read_unlock(&controller->rw_lock);
	CDBG("unlocked controller %pK name %s rw_lock %pK\n",
		controller, controller->name, &controller->rw_lock);

	CDBG("Status Registers read Successful\n");

+10 −9
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ struct cam_vfe_hw_get_hw_cap {
 *                           (Default is Master in case of Single VFE)
 * @dual_slave_core:         If Master and Slave exists, HW Index of Slave
 * @cdm_ops:                 CDM operations
 * @ctx:                     Context data
 */
struct cam_vfe_hw_vfe_out_acquire_args {
	struct cam_isp_resource_node      *rsrc_node;
@@ -118,6 +119,7 @@ struct cam_vfe_hw_vfe_out_acquire_args {
	uint32_t                           is_master;
	uint32_t                           dual_slave_core;
	struct cam_cdm_utils_ops          *cdm_ops;
	void                              *ctx;
};

/*
@@ -192,22 +194,21 @@ struct cam_vfe_top_irq_evt_payload {
 *
 * @list:                    list_head node for the payload
 * @core_index:              Index of VFE HW that generated this IRQ event
 * @core_info:               Private data of handler in bottom half context
 * @evt_id:                  IRQ event
 * @irq_reg_val:             IRQ and Error register values, read when IRQ was
 *                           handled
 * @error_type:              Identify different errors
 * @ts:                      Timestamp
 * @ctx:                     Context data received during acquire
 */
struct cam_vfe_bus_irq_evt_payload {
	struct list_head            list;
	uint32_t                    core_index;
	void                        *core_info;
	uint32_t                    evt_id;
	uint32_t                    irq_reg_val[CAM_IFE_BUS_IRQ_REGISTERS_MAX];
	uint32_t                    error_type;
	struct cam_vfe_bus_ver2_priv *bus_priv;
	struct cam_isp_timestamp    ts;
	void                       *ctx;
};

/*
+26 −28
Original line number Diff line number Diff line
@@ -51,11 +51,6 @@ static uint32_t top_reset_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x00000000,
};

static uint32_t bus_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x00000200,
	0x00000000,
};

static int cam_vfe_get_evt_payload(struct cam_vfe_hw_core_info *core_info,
	struct cam_vfe_top_irq_evt_payload    **evt_payload)
{
@@ -188,15 +183,25 @@ int cam_vfe_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size)

	CDBG("Enable soc done\n");

	rc = core_info->vfe_bus->hw_ops.init(core_info->vfe_bus->bus_priv,
		NULL, 0);
	if (rc) {
		pr_err("Bus HW init Failed rc=%d\n", rc);
		goto disable_soc;
	}

	/* Do HW Reset */
	rc = cam_vfe_reset(hw_priv, NULL, 0);
	if (rc) {
		pr_err("Reset Failed\n");
		goto disable_soc;
		pr_err("Reset Failed rc=%d\n", rc);
		goto deinit_bus;
	}

	return 0;

deinit_bus:
	core_info->vfe_bus->hw_ops.deinit(core_info->vfe_bus->bus_priv,
		NULL, 0);
disable_soc:
	cam_vfe_disable_soc_resources(soc_info);
decrement_open_cnt:
@@ -382,10 +387,11 @@ int cam_vfe_reserve(void *hw_priv, void *reserve_args, uint32_t arg_size)
		rc = core_info->vfe_top->hw_ops.reserve(
			core_info->vfe_top->top_priv,
			acquire,
			sizeof(acquire));
			sizeof(*acquire));
	else if (acquire->rsrc_type == CAM_ISP_RESOURCE_VFE_OUT)
		rc = core_info->vfe_bus->acquire_resource(
			core_info->vfe_bus->bus_priv, acquire);
		rc = core_info->vfe_bus->hw_ops.reserve(
			core_info->vfe_bus->bus_priv, acquire,
			sizeof(*acquire));
	else
		pr_err("Invalid res type:%d\n", acquire->rsrc_type);

@@ -415,10 +421,11 @@ int cam_vfe_release(void *hw_priv, void *release_args, uint32_t arg_size)
	if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN)
		rc = core_info->vfe_top->hw_ops.release(
			core_info->vfe_top->top_priv, isp_res,
			sizeof(struct cam_isp_resource_node));
			sizeof(*isp_res));
	else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT)
		rc = core_info->vfe_bus->release_resource(
			core_info->vfe_bus->bus_priv, isp_res);
		rc = core_info->vfe_bus->hw_ops.release(
			core_info->vfe_bus->bus_priv, isp_res,
			sizeof(*isp_res));
	else
		pr_err("Invalid res type:%d\n", isp_res->res_type);

@@ -468,16 +475,7 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size)
		else
			pr_err("Error! subscribe irq controller failed\n");
	} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
		isp_res->irq_handle = cam_irq_controller_subscribe_irq(
			core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_2,
			bus_irq_reg_mask, &core_info->irq_payload,
			core_info->vfe_bus->top_half_handler,
			cam_ife_mgr_do_tasklet_buf_done,
			isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
		if (isp_res->irq_handle > 0)
			rc = core_info->vfe_bus->start_resource(isp_res);
		else
			pr_err("Error! subscribe irq controller failed\n");
		rc = core_info->vfe_bus->hw_ops.start(isp_res, NULL, 0);
	} else {
		pr_err("Invalid res type:%d\n", isp_res->res_type);
	}
@@ -513,7 +511,7 @@ int cam_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size)
	} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
		cam_irq_controller_unsubscribe_irq(
			core_info->vfe_irq_controller, isp_res->irq_handle);
		rc = core_info->vfe_bus->stop_resource(isp_res);
		rc = core_info->vfe_bus->hw_ops.stop(isp_res, NULL, 0);
	} else {
		pr_err("Invalid res type:%d\n", isp_res->res_type);
	}
@@ -560,7 +558,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,

		break;
	case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
		rc = core_info->vfe_bus->process_cmd(
		rc = core_info->vfe_bus->hw_ops.process_cmd(
			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
			arg_size);
		break;
@@ -614,9 +612,9 @@ int cam_vfe_core_init(struct cam_vfe_hw_core_info *core_info,
		goto deinit_controller;
	}

	rc = cam_vfe_bus_init(vfe_hw_info->bus_version,
		soc_info->reg_map[0].mem_base, hw_intf,
		vfe_hw_info->bus_hw_info, NULL, &core_info->vfe_bus);
	rc = cam_vfe_bus_init(vfe_hw_info->bus_version, soc_info, hw_intf,
		vfe_hw_info->bus_hw_info, core_info->vfe_irq_controller,
		&core_info->vfe_bus);
	if (rc) {
		pr_err("Error! cam_vfe_bus_init failed\n");
		goto deinit_top;
+3 −0
Original line number Diff line number Diff line
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cdm/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_core/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/include
Loading