Browse Source

msm: camera: isp: Move Bus IRQ subscribe to start

Currently, bus IRQs are subscribed before start, which
will result in IRQ mask to be reset when CSID global
SWI reset is present on certain targets. Move the IRQ
subscribe/unsubscribe calls to start/stop in vfe bus to
help retain the mask value.

CRs-Fixed: 2841729
Change-Id: I7c10fda9c82bb5f1601d3fd67cabda0a5abc275b
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Mukund Madhusudan Atre 4 years ago
parent
commit
d38f4e07d1
1 changed files with 124 additions and 85 deletions
  1. 124 85
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

+ 124 - 85
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -105,6 +105,7 @@ struct cam_vfe_bus_ver3_common_data {
 	bool                                        hw_init;
 	bool                                        support_consumed_addr;
 	bool                                        disable_ubwc_comp;
+	bool                                        init_irq_subscribed;
 	cam_hw_mgr_event_cb_func                    event_cb;
 	int                        rup_irq_handle[CAM_VFE_BUS_VER3_SRC_GRP_MAX];
 };
@@ -485,6 +486,12 @@ static const struct cam_vfe_bus_error_info vfe_lite_error_list[] = {
 	}
 };
 
+static void cam_vfe_bus_ver3_unsubscribe_init_irq(
+	struct cam_vfe_bus_ver3_priv          *bus_priv);
+
+static int cam_vfe_bus_ver3_subscribe_init_irq(
+	struct cam_vfe_bus_ver3_priv          *bus_priv);
+
 static int cam_vfe_bus_ver3_process_cmd(
 	struct cam_isp_resource_node *priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
@@ -2200,6 +2207,13 @@ static int cam_vfe_bus_ver3_start_vfe_out(
 		return -EACCES;
 	}
 
+	/* subscribe when first out rsrc is streamed on */
+	if (!rsrc_data->common_data->init_irq_subscribed) {
+		rc = cam_vfe_bus_ver3_subscribe_init_irq(rsrc_data->bus_priv);
+		if (rc)
+			return rc;
+	}
+
 	for (i = 0; i < rsrc_data->num_wm; i++)
 		rc = cam_vfe_bus_ver3_start_wm(&rsrc_data->wm_res[i]);
 
@@ -2307,6 +2321,9 @@ static int cam_vfe_bus_ver3_stop_vfe_out(
 		vfe_out->irq_handle = 0;
 	}
 
+	if (rsrc_data->common_data->init_irq_subscribed)
+		cam_vfe_bus_ver3_unsubscribe_init_irq(rsrc_data->bus_priv);
+
 	vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
 	return rc;
 }
@@ -2811,6 +2828,111 @@ static int cam_vfe_bus_ver3_err_irq_bottom_half(
 	return 0;
 }
 
+static void cam_vfe_bus_ver3_unsubscribe_init_irq(
+	struct cam_vfe_bus_ver3_priv          *bus_priv)
+{
+	int rc = 0;
+
+	if (bus_priv->error_irq_handle) {
+		rc = cam_irq_controller_unsubscribe_irq(
+			bus_priv->common_data.bus_irq_controller,
+			bus_priv->error_irq_handle);
+		if (rc)
+			CAM_WARN(CAM_ISP, "failed to unsubscribe error irqs");
+
+		bus_priv->error_irq_handle = 0;
+	}
+
+	if (bus_priv->bus_irq_handle) {
+		rc = cam_irq_controller_unsubscribe_irq(
+			bus_priv->common_data.vfe_irq_controller,
+			bus_priv->bus_irq_handle);
+		if (rc)
+			CAM_WARN(CAM_ISP, "failed to unsubscribe top irq");
+
+		bus_priv->bus_irq_handle = 0;
+	}
+
+	if (bus_priv->rup_irq_handle) {
+		rc = cam_irq_controller_unsubscribe_irq(
+			bus_priv->common_data.vfe_irq_controller,
+			bus_priv->rup_irq_handle);
+		if (rc)
+			CAM_WARN(CAM_ISP, "failed to unsubscribe rup done irq");
+
+		bus_priv->rup_irq_handle = 0;
+	}
+
+	bus_priv->common_data.init_irq_subscribed = false;
+	CAM_DBG(CAM_ISP, "BUS init irq unsubscribed");
+}
+
+static int cam_vfe_bus_ver3_subscribe_init_irq(
+	struct cam_vfe_bus_ver3_priv          *bus_priv)
+{
+	uint32_t top_irq_reg_mask[3] = {0};
+
+	/* Subscribe top IRQ */
+	top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift);
+
+	bus_priv->bus_irq_handle = cam_irq_controller_subscribe_irq(
+		bus_priv->common_data.vfe_irq_controller,
+		CAM_IRQ_PRIORITY_4,
+		top_irq_reg_mask,
+		bus_priv,
+		cam_vfe_bus_ver3_handle_bus_irq,
+		NULL,
+		NULL,
+		NULL);
+
+	if (bus_priv->bus_irq_handle < 1) {
+		CAM_ERR(CAM_ISP, "Failed to subscribe BUS (buf_done) IRQ");
+		bus_priv->bus_irq_handle = 0;
+		return -EFAULT;
+	}
+
+
+	if (bus_priv->tasklet_info != NULL) {
+		bus_priv->error_irq_handle = cam_irq_controller_subscribe_irq(
+			bus_priv->common_data.bus_irq_controller,
+			CAM_IRQ_PRIORITY_0,
+			bus_error_irq_mask,
+			bus_priv,
+			cam_vfe_bus_ver3_err_irq_top_half,
+			cam_vfe_bus_ver3_err_irq_bottom_half,
+			bus_priv->tasklet_info,
+			&tasklet_bh_api);
+
+		if (bus_priv->error_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "Failed to subscribe BUS Error IRQ");
+			bus_priv->error_irq_handle = 0;
+			return -EFAULT;
+		}
+	}
+
+	if (bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) {
+		bus_priv->rup_irq_handle = cam_irq_controller_subscribe_irq(
+			bus_priv->common_data.vfe_irq_controller,
+			CAM_IRQ_PRIORITY_2,
+			top_irq_reg_mask,
+			bus_priv,
+			cam_vfe_bus_ver3_handle_rup_irq,
+			NULL,
+			NULL,
+			NULL);
+
+		if (bus_priv->rup_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ");
+			bus_priv->rup_irq_handle = 0;
+			return -EFAULT;
+		}
+	}
+
+	bus_priv->common_data.init_irq_subscribed = true;
+	CAM_DBG(CAM_ISP, "BUS irq subscribed");
+	return 0;
+}
+
 static void cam_vfe_bus_ver3_update_ubwc_meta_addr(
 	uint32_t *reg_val_pair,
 	uint32_t  *j,
@@ -3465,7 +3587,6 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv,
 	void *init_hw_args, uint32_t arg_size)
 {
 	struct cam_vfe_bus_ver3_priv    *bus_priv = hw_priv;
-	uint32_t                         top_irq_reg_mask[3] = {0};
 
 	if (!bus_priv) {
 		CAM_ERR(CAM_ISP, "Invalid args");
@@ -3475,60 +3596,6 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv,
 	if (bus_priv->common_data.hw_init)
 		return 0;
 
-	top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift);
-
-	bus_priv->bus_irq_handle = cam_irq_controller_subscribe_irq(
-		bus_priv->common_data.vfe_irq_controller,
-		CAM_IRQ_PRIORITY_4,
-		top_irq_reg_mask,
-		bus_priv,
-		cam_vfe_bus_ver3_handle_bus_irq,
-		NULL,
-		NULL,
-		NULL);
-
-	if (bus_priv->bus_irq_handle < 1) {
-		CAM_ERR(CAM_ISP, "Failed to subscribe BUS (buf_done) IRQ");
-		bus_priv->bus_irq_handle = 0;
-		return -EFAULT;
-	}
-
-	if (bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) {
-		bus_priv->rup_irq_handle = cam_irq_controller_subscribe_irq(
-			bus_priv->common_data.vfe_irq_controller,
-			CAM_IRQ_PRIORITY_2,
-			top_irq_reg_mask,
-			bus_priv,
-			cam_vfe_bus_ver3_handle_rup_irq,
-			NULL,
-			NULL,
-			NULL);
-
-		if (bus_priv->rup_irq_handle < 1) {
-			CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ");
-			bus_priv->rup_irq_handle = 0;
-			return -EFAULT;
-		}
-	}
-
-	if (bus_priv->tasklet_info != NULL) {
-		bus_priv->error_irq_handle = cam_irq_controller_subscribe_irq(
-			bus_priv->common_data.bus_irq_controller,
-			CAM_IRQ_PRIORITY_0,
-			bus_error_irq_mask,
-			bus_priv,
-			cam_vfe_bus_ver3_err_irq_top_half,
-			cam_vfe_bus_ver3_err_irq_bottom_half,
-			bus_priv->tasklet_info,
-			&tasklet_bh_api);
-
-		if (bus_priv->error_irq_handle < 1) {
-			CAM_ERR(CAM_ISP, "Failed to subscribe BUS Error IRQ");
-			bus_priv->error_irq_handle = 0;
-			return -EFAULT;
-		}
-	}
-
 	/* We take the controller only if the buf done is supported on vfe side
 	 * for some hw, it is taken from IP extenal to VFE like CSID
 	 */
@@ -3536,15 +3603,6 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv,
 		bus_priv->common_data.buf_done_controller =
 			bus_priv->common_data.bus_irq_controller;
 
-	/* no clock gating at bus input */
-	CAM_DBG(CAM_ISP, "Overriding clock gating at bus input");
-	cam_io_w_mb(0x3FFFFFF, bus_priv->common_data.mem_base +
-		bus_priv->common_data.common_reg->cgc_ovd);
-
-	/* BUS_WR_TEST_BUS_CTRL */
-	cam_io_w_mb(0x0, bus_priv->common_data.mem_base +
-		bus_priv->common_data.common_reg->test_bus_ctrl);
-
 	bus_priv->common_data.hw_init = true;
 
 	return 0;
@@ -3565,27 +3623,6 @@ static int cam_vfe_bus_ver3_deinit_hw(void *hw_priv,
 	if (!bus_priv->common_data.hw_init)
 		return 0;
 
-	if (bus_priv->error_irq_handle) {
-		rc = cam_irq_controller_unsubscribe_irq(
-			bus_priv->common_data.bus_irq_controller,
-			bus_priv->error_irq_handle);
-		bus_priv->error_irq_handle = 0;
-	}
-
-	if (bus_priv->bus_irq_handle) {
-		rc = cam_irq_controller_unsubscribe_irq(
-			bus_priv->common_data.vfe_irq_controller,
-			bus_priv->bus_irq_handle);
-		bus_priv->bus_irq_handle = 0;
-	}
-
-	if (bus_priv->rup_irq_handle) {
-		rc = cam_irq_controller_unsubscribe_irq(
-			bus_priv->common_data.vfe_irq_controller,
-			bus_priv->rup_irq_handle);
-		bus_priv->rup_irq_handle = 0;
-	}
-
 	spin_lock_irqsave(&bus_priv->common_data.spin_lock, flags);
 	INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
 	for (i = 0; i < CAM_VFE_BUS_VER3_PAYLOAD_MAX; i++) {
@@ -3808,6 +3845,7 @@ int cam_vfe_bus_ver3_init(
 	bus_priv->common_data.supported_irq      = ver3_hw_info->supported_irq;
 	bus_priv->common_data.comp_config_needed =
 		ver3_hw_info->comp_cfg_needed;
+	bus_priv->common_data.init_irq_subscribed = false;
 
 	if (bus_priv->num_out >= CAM_VFE_BUS_VER3_VFE_OUT_MAX) {
 		CAM_ERR(CAM_ISP, "number of vfe out:%d more than max value:%d ",
@@ -3962,6 +4000,7 @@ int cam_vfe_bus_ver3_deinit(
 	for (i = 0; i < CAM_VFE_BUS_VER3_PAYLOAD_MAX; i++)
 		INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
 	bus_priv->common_data.hw_init = false;
+	bus_priv->common_data.init_irq_subscribed = false;
 	spin_unlock_irqrestore(&bus_priv->common_data.spin_lock, flags);
 
 	for (i = 0; i < bus_priv->num_comp_grp; i++) {