Просмотр исходного кода

Merge "msm: camera: isp: Move Bus IRQ subscribe to start" into camera-kernel.lnx.5.0

Haritha Chintalapati 4 лет назад
Родитель
Сommit
6d805cbaa1
1 измененных файлов с 124 добавлено и 85 удалено
  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++) {