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

Commit 9c2abd25 authored by Venkat Chinta's avatar Venkat Chinta
Browse files

msm: camera: isp: Add reset to deinit sequence



This change adds vfe reset to vfe hardware deinit. This ensures
that the hardware is in a clean state before turning off
clocks. It also updates error irq masks for improved error
handling.

Change-Id: I2dbca0c7ba0ccce58675c563ef139fb9187cad15
Signed-off-by: default avatarVenkat Chinta <vchinta@codeaurora.org>
Signed-off-by: default avatarVishalsingh Hajeri <vhajeri@codeaurora.org>
parent 8a550616
Loading
Loading
Loading
Loading
+24 −26
Original line number Diff line number Diff line
@@ -32,17 +32,17 @@ static uint32_t irq_reg_offset[CAM_IFE_IRQ_REGISTERS_MAX] = {
};

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

static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
	0x00000000,
	0x0003FC00,
	0x0FFF7EBC,
};

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

@@ -89,9 +89,10 @@ int cam_vfe_put_evt_payload(void *core_info,
	spin_lock_irqsave(&vfe_core_info->spin_lock, flags);
	(*evt_payload)->error_type = 0;
	list_add_tail(&(*evt_payload)->list, &vfe_core_info->free_payload_list);
	*evt_payload = NULL;
	spin_unlock_irqrestore(&vfe_core_info->spin_lock, flags);

	*evt_payload = NULL;

	return 0;
}

@@ -156,6 +157,7 @@ static int cam_vfe_irq_err_top_half(uint32_t evt_id,
	struct cam_vfe_irq_handler_priv     *handler_priv;
	struct cam_vfe_top_irq_evt_payload  *evt_payload;
	struct cam_vfe_hw_core_info         *core_info;
	bool                                 error_flag = false;

	CAM_DBG(CAM_ISP, "IRQ status_0 = %x, IRQ status_1 = %x",
		th_payload->evt_status_arr[0], th_payload->evt_status_arr[1]);
@@ -166,14 +168,20 @@ static int cam_vfe_irq_err_top_half(uint32_t evt_id,
	 *  need to handle overflow condition here, otherwise irq storm
	 *  will block everything
	 */

	if (th_payload->evt_status_arr[1]) {
		CAM_ERR(CAM_ISP, "IRQ status_1: %x, Masking all interrupts",
	if (th_payload->evt_status_arr[1] ||
		(th_payload->evt_status_arr[0] & camif_irq_err_reg_mask[0])) {
		CAM_ERR(CAM_ISP,
			"Encountered Error: vfe:%d:  Irq_status0=0x%x Status1=0x%x",
			handler_priv->core_index, th_payload->evt_status_arr[0],
			th_payload->evt_status_arr[1]);
		CAM_ERR(CAM_ISP,
			"Stopping further IRQ processing from this HW index=%d",
			handler_priv->core_index);
		cam_irq_controller_disable_irq(core_info->vfe_irq_controller,
			core_info->irq_err_handle);
		cam_irq_controller_clear_and_mask(evt_id,
			core_info->vfe_irq_controller);
		error_flag = true;
	}

	rc  = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
@@ -200,7 +208,9 @@ static int cam_vfe_irq_err_top_half(uint32_t evt_id,
			irq_reg_offset[i]);
	}

	CAM_DBG(CAM_ISP, "Violation status = %x", evt_payload->irq_reg_val[2]);
	if (error_flag)
		CAM_INFO(CAM_ISP, "Violation status = %x",
			evt_payload->irq_reg_val[2]);

	th_payload->evt_payload_priv = evt_payload;

@@ -291,6 +301,8 @@ int cam_vfe_deinit_hw(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
	struct cam_vfe_hw_core_info       *core_info = NULL;
	struct cam_isp_resource_node      *isp_res = NULL;
	int rc = 0;
	uint32_t                           reset_core_args =
					CAM_VFE_HW_RESET_HW_AND_REG;

	CAM_DBG(CAM_ISP, "Enter");
	if (!hw_priv) {
@@ -327,6 +339,8 @@ int cam_vfe_deinit_hw(void *hw_priv, void *deinit_hw_args, uint32_t arg_size)
			CAM_ERR(CAM_ISP, "deinit failed");
	}

	rc = cam_vfe_reset(hw_priv, &reset_core_args, sizeof(uint32_t));

	/* Turn OFF Regulators, Clocks and other SOC resources */
	CAM_DBG(CAM_ISP, "Disable SOC resource");
	rc = cam_vfe_disable_soc_resources(soc_info);
@@ -373,7 +387,7 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)

	reinit_completion(&vfe_hw->hw_complete);

	CAM_DBG(CAM_ISP, "calling RESET");
	CAM_DBG(CAM_ISP, "calling RESET on vfe %d", soc_info->index);
	core_info->vfe_top->hw_ops.reset(core_info->vfe_top->top_priv,
		reset_core_args, arg_size);
	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
@@ -416,23 +430,6 @@ static int cam_vfe_irq_top_half(uint32_t evt_id,
	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]);

	/*
	 *  need to handle non-recoverable condition here, otherwise irq storm
	 *  will block everything.
	 */
	if (th_payload->evt_status_arr[0] & 0x3FC00) {
		CAM_ERR(CAM_ISP,
			"Encountered Error Irq_status0=0x%x Status1=0x%x",
			th_payload->evt_status_arr[0],
			th_payload->evt_status_arr[1]);
		CAM_ERR(CAM_ISP,
			"Stopping further IRQ processing from this HW index=%d",
			handler_priv->core_index);
		cam_io_w(0, handler_priv->mem_base + 0x60);
		cam_io_w(0, handler_priv->mem_base + 0x5C);
		return 0;
	}

	rc  = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
	if (rc) {
		CAM_ERR_RATE_LIMIT(CAM_ISP,
@@ -705,6 +702,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
	case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
	case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
	case CAM_ISP_HW_CMD_STRIPE_UPDATE:
	case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
		rc = core_info->vfe_bus->hw_ops.process_cmd(
			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
			arg_size);