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

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

Merge "msm: ais: fix start stop stability"

parents 96affc60 ba0f68ec
Loading
Loading
Loading
Loading
+27 −27
Original line number Original line Diff line number Diff line
@@ -139,26 +139,23 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev,


	rc = csid_drv->hw_ops.init(
	rc = csid_drv->hw_ops.init(
		csid_drv->hw_priv, rdi_init, cmd_size);
		csid_drv->hw_priv, rdi_init, cmd_size);
	if (!rc) {
	if (rc)
		goto fail_csid_init;

	rc = vfe_drv->hw_ops.init(
	rc = vfe_drv->hw_ops.init(
			vfe_drv->hw_priv, rdi_init, cmd_size);
			vfe_drv->hw_priv, rdi_init, cmd_size);
	if (rc)
	if (rc)
		goto fail_vfe_init;
		goto fail_vfe_init;
	}


	if (!rc) {
	rc = csid_drv->hw_ops.reserve(
	rc = csid_drv->hw_ops.reserve(
			csid_drv->hw_priv, rdi_init, cmd_size);
			csid_drv->hw_priv, rdi_init, cmd_size);
	if (rc)
	if (rc)
		goto fail_csid_reserve;
		goto fail_csid_reserve;
	}


	if (!rc) {
	rc = vfe_drv->hw_ops.reserve(
	rc = vfe_drv->hw_ops.reserve(
			vfe_drv->hw_priv, rdi_init, cmd_size);
			vfe_drv->hw_priv, rdi_init, cmd_size);
	if (rc)
	if (rc)
		goto fail_vfe_reserve;
		goto fail_vfe_reserve;
	}


	return rc;
	return rc;


@@ -171,7 +168,7 @@ static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev,
fail_vfe_init:
fail_vfe_init:
	csid_drv->hw_ops.deinit(
	csid_drv->hw_ops.deinit(
		csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit));
		csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit));

fail_csid_init:
	return rc;
	return rc;
}
}


@@ -189,6 +186,7 @@ static int ais_ife_cmd_release(struct ais_ife_dev *p_ife_dev,


	rc = csid_drv->hw_ops.release(
	rc = csid_drv->hw_ops.release(
		csid_drv->hw_priv, rdi_deinit, cmd_size);
		csid_drv->hw_priv, rdi_deinit, cmd_size);

	tmp = vfe_drv->hw_ops.release(
	tmp = vfe_drv->hw_ops.release(
		vfe_drv->hw_priv, rdi_deinit, cmd_size);
		vfe_drv->hw_priv, rdi_deinit, cmd_size);
	if (!rc)
	if (!rc)
@@ -313,20 +311,22 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg)
				cmd->size)) {
				cmd->size)) {
			rc = -EFAULT;
			rc = -EFAULT;
		} else {
		} else {
			rc = csid_drv->hw_ops.start(
			rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv,
				csid_drv->hw_priv, &rdi_start, cmd->size);
				&rdi_start, cmd->size);
			if (!rc) {
			if (!rc) {
				rc = csid_drv->hw_ops.start(
					csid_drv->hw_priv, &rdi_start,
					cmd->size);
				if (rc) {
					struct ais_ife_rdi_stop_args rdi_stop;
					struct ais_ife_rdi_stop_args rdi_stop;


					rdi_stop.path = rdi_start.path;
					rdi_stop.path = rdi_start.path;
				rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv,
					vfe_drv->hw_ops.stop(vfe_drv->hw_priv,
					&rdi_start, cmd->size);
				if (rc)
					csid_drv->hw_ops.stop(csid_drv->hw_priv,
						&rdi_stop, sizeof(rdi_stop));
						&rdi_stop, sizeof(rdi_stop));
				}
				}
			}
			}
		}
		}
	}
		break;
		break;
	case AIS_IFE_STOP: {
	case AIS_IFE_STOP: {
		struct ais_ife_rdi_stop_args rdi_stop;
		struct ais_ife_rdi_stop_args rdi_stop;
@@ -341,10 +341,10 @@ static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg)
		} else {
		} else {
			int tmp;
			int tmp;


			rc = vfe_drv->hw_ops.stop(
			rc = csid_drv->hw_ops.stop(
				vfe_drv->hw_priv, &rdi_stop, cmd->size);
			tmp = csid_drv->hw_ops.stop(
				csid_drv->hw_priv, &rdi_stop, cmd->size);
				csid_drv->hw_priv, &rdi_stop, cmd->size);
			tmp = vfe_drv->hw_ops.stop(
				vfe_drv->hw_priv, &rdi_stop, cmd->size);
			if (!rc)
			if (!rc)
				rc = tmp;
				rc = tmp;
		}
		}
+25 −21
Original line number Original line Diff line number Diff line
@@ -214,10 +214,8 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw,
		return -EINVAL;
		return -EINVAL;
	}
	}


	reset_strb_addr =
	reset_strb_addr = csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
			csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
	complete = &csid_hw->csid_rdi_complete[id];
	complete =
			&csid_hw->csid_rdi_complete[id];


	/* Enable path reset done interrupt */
	/* Enable path reset done interrupt */
	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -226,7 +224,7 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw,
	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
			csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
			csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);


	init_completion(complete);
	reinit_completion(complete);
	reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
	reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;


	/* Reset the corresponding ife csid path */
	/* Reset the corresponding ife csid path */
@@ -235,11 +233,11 @@ static int ais_ife_csid_path_reset(struct ais_ife_csid_hw *csid_hw,


	rc = wait_for_completion_timeout(complete,
	rc = wait_for_completion_timeout(complete,
		msecs_to_jiffies(IFE_CSID_TIMEOUT));
		msecs_to_jiffies(IFE_CSID_TIMEOUT));
	if (rc <= 0) {
	if (rc) {
		CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
		rc = 0;
			 csid_hw->hw_intf->hw_idx,
	} else {
			reset_path,  rc);
		CAM_ERR(CAM_ISP, "CSID:%d RDI%d reset fail",
		if (rc == 0)
			 csid_hw->hw_intf->hw_idx, reset_path, rc);
		rc = -ETIMEDOUT;
		rc = -ETIMEDOUT;
	}
	}


@@ -815,6 +813,7 @@ static int ais_ife_csid_enable_rdi_path(
	soc_info = &csid_hw->hw_info->soc_info;
	soc_info = &csid_hw->hw_info->soc_info;
	path_data = &csid_hw->rdi_cfg[id];
	path_data = &csid_hw->rdi_cfg[id];


	path_data->init_frame_drop = 1;
	path_data->sof_cnt = 0;
	path_data->sof_cnt = 0;


	/* Enable the required RDI interrupts */
	/* Enable the required RDI interrupts */
@@ -1326,7 +1325,7 @@ static int ais_ife_csid_start(void *hw_priv, void *start_args,


	if (start_cmd->path >= csid_reg->cmn_reg->num_rdis ||
	if (start_cmd->path >= csid_reg->cmn_reg->num_rdis ||
		!csid_reg->rdi_reg[start_cmd->path]) {
		!csid_reg->rdi_reg[start_cmd->path]) {
		CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
		CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
			csid_hw->hw_intf->hw_idx, start_cmd->path);
			csid_hw->hw_intf->hw_idx, start_cmd->path);
		rc = -EINVAL;
		rc = -EINVAL;
		goto end;
		goto end;
@@ -1367,7 +1366,7 @@ static int ais_ife_csid_stop(void *hw_priv,


	if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis ||
	if (stop_cmd->path >= csid_reg->cmn_reg->num_rdis ||
		!csid_reg->rdi_reg[stop_cmd->path]) {
		!csid_reg->rdi_reg[stop_cmd->path]) {
		CAM_DBG(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
		CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
			csid_hw->hw_intf->hw_idx, stop_cmd->path);
			csid_hw->hw_intf->hw_idx, stop_cmd->path);
		rc = -EINVAL;
		rc = -EINVAL;
		goto end;
		goto end;
@@ -1677,6 +1676,7 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data)
	const struct ais_ife_csid_rdi_reg_offset       *rdi_reg;
	const struct ais_ife_csid_rdi_reg_offset       *rdi_reg;
	uint32_t i;
	uint32_t i;
	uint32_t val, val2;
	uint32_t val, val2;
	uint32_t warn_cnt = 0;
	bool fatal_err_detected = false;
	bool fatal_err_detected = false;
	uint32_t sof_irq_debug_en = 0;
	uint32_t sof_irq_debug_en = 0;
	unsigned long flags;
	unsigned long flags;
@@ -1778,27 +1778,29 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data)
		}
		}
		if (irq_status[CSID_IRQ_STATUS_RX] &
		if (irq_status[CSID_IRQ_STATUS_RX] &
			CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
			CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
			csid_hw->error_irq_count++;
			warn_cnt++;
		}
		}
		if (irq_status[CSID_IRQ_STATUS_RX] &
		if (irq_status[CSID_IRQ_STATUS_RX] &
			CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
			CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
			csid_hw->error_irq_count++;
			warn_cnt++;
		}
		}
		if (irq_status[CSID_IRQ_STATUS_RX] &
		if (irq_status[CSID_IRQ_STATUS_RX] &
			CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
			CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
			csid_hw->error_irq_count++;
			warn_cnt++;
		}
		}
		if (irq_status[CSID_IRQ_STATUS_RX] &
		if (irq_status[CSID_IRQ_STATUS_RX] &
			CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
			CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
			csid_hw->error_irq_count++;
			warn_cnt++;
		}
		}
	}
	}


	csid_hw->error_irq_count += warn_cnt;

	if (csid_hw->error_irq_count >
	if (csid_hw->error_irq_count >
		AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
		AIS_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
		fatal_err_detected = true;
		fatal_err_detected = true;
		csid_hw->error_irq_count = 0;
		csid_hw->error_irq_count = 0;
	} else if (csid_hw->error_irq_count) {
	} else if (warn_cnt) {
		uint64_t timestamp;
		uint64_t timestamp;


		timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
		timestamp = (uint64_t)((ts.tv_sec * 1000000000) + ts.tv_nsec);
@@ -1951,18 +1953,20 @@ static irqreturn_t ais_ife_csid_irq(int irq_num, void *data)
			(path_data->init_frame_drop) &&
			(path_data->init_frame_drop) &&
			(path_data->state ==
			(path_data->state ==
			AIS_ISP_RESOURCE_STATE_STREAMING)) {
			AIS_ISP_RESOURCE_STATE_STREAMING)) {
			path_data[i].sof_cnt++;
			path_data->sof_cnt++;
			CAM_DBG(CAM_ISP,
			CAM_DBG(CAM_ISP,
				"CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d",
				"CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d",
				csid_hw->hw_intf->hw_idx, i,
				csid_hw->hw_intf->hw_idx, i,
				path_data[i].sof_cnt,
				path_data->sof_cnt,
				path_data->init_frame_drop);
				path_data->init_frame_drop);
			if (path_data[i].sof_cnt ==
			if (path_data->sof_cnt ==
				path_data->init_frame_drop) {
				path_data->init_frame_drop) {
				cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY,
				cam_io_w_mb(AIS_CSID_RESUME_AT_FRAME_BOUNDARY,
					soc_info->reg_map[0].mem_base +
					soc_info->reg_map[0].mem_base +
					rdi_reg->csid_rdi_ctrl_addr);
					rdi_reg->csid_rdi_ctrl_addr);


				path_data->init_frame_drop = 0;

				if (!(csid_hw->csid_debug &
				if (!(csid_hw->csid_debug &
					CSID_DEBUG_ENABLE_SOF_IRQ)) {
					CSID_DEBUG_ENABLE_SOF_IRQ)) {
					val = cam_io_r_mb(
					val = cam_io_r_mb(
+67 −31
Original line number Original line Diff line number Diff line
@@ -99,7 +99,7 @@ static int ais_vfe_bus_hw_init(struct ais_vfe_hw_core_info *core_info)
	cam_io_w_mb(core_info->irq_mask0,
	cam_io_w_mb(core_info->irq_mask0,
		core_info->mem_base + AIS_VFE_IRQ_MASK0);
		core_info->mem_base + AIS_VFE_IRQ_MASK0);


	cam_io_w_mb(0x7800,
	cam_io_w_mb(0x7801,
		core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset);
		core_info->mem_base + bus_hw_irq_regs[0].mask_reg_offset);
	cam_io_w_mb(0x0,
	cam_io_w_mb(0x0,
		core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset);
		core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset);
@@ -220,7 +220,8 @@ static int ais_vfe_reset(void *hw_priv,
	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");


	/* Wait for Completion or Timeout of 500ms */
	/* Wait for Completion or Timeout of 500ms */
	rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500);
	rc = wait_for_completion_timeout(&vfe_hw->hw_complete,
					msecs_to_jiffies(500));
	if (rc) {
	if (rc) {
		rc = 0;
		rc = 0;
	} else {
	} else {
@@ -622,17 +623,28 @@ int ais_vfe_stop(void *hw_priv, void *stop_args, uint32_t arg_size)


	rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW;
	rdi_path->state = AIS_ISP_RESOURCE_STATE_INIT_HW;


	core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path);
	cam_io_w_mb(core_info->bus_wr_mask1,
		core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset);

	/* Disable WM and reg-update */
	/* Disable WM and reg-update */
	cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg);
	cam_io_w_mb(0x0, core_info->mem_base + client_regs->cfg);
	cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base +
	cam_io_w_mb(AIS_VFE_REGUP_RDI_ALL, core_info->mem_base +
			top_hw_info->common_reg->reg_update_cmd);
			top_hw_info->common_reg->reg_update_cmd);


	/* issue bus wr reset and wait for reset ack */
	reinit_completion(&vfe_hw->hw_complete);

	cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base +
	cam_io_w_mb((1 << stop_cmd->path), core_info->mem_base +
			bus_hw_info->common_reg.sw_reset);
			bus_hw_info->common_reg.sw_reset);


	core_info->bus_wr_mask1 &= ~(1 << stop_cmd->path);
	/* Wait for completion or timeout of 50ms */
	cam_io_w_mb(core_info->bus_wr_mask1,
	rc = wait_for_completion_timeout(&vfe_hw->hw_complete,
		core_info->mem_base + bus_hw_irq_regs[1].mask_reg_offset);
					msecs_to_jiffies(50));
	if (rc)
		rc = 0;
	else
		CAM_WARN(CAM_ISP, "Reset Bus WR timeout");


	ais_clear_rdi_path(rdi_path);
	ais_clear_rdi_path(rdi_path);


@@ -896,7 +908,8 @@ static int ais_vfe_handle_error(


static void ais_vfe_bus_handle_client_frame_done(
static void ais_vfe_bus_handle_client_frame_done(
	struct ais_vfe_hw_core_info *core_info,
	struct ais_vfe_hw_core_info *core_info,
	enum ais_ife_output_path_id path)
	enum ais_ife_output_path_id path,
	uint32_t last_addr)
{
{
	struct ais_vfe_rdi_output         *rdi_path = NULL;
	struct ais_vfe_rdi_output         *rdi_path = NULL;
	struct ais_vfe_buffer_t           *vfe_buf = NULL;
	struct ais_vfe_buffer_t           *vfe_buf = NULL;
@@ -925,7 +938,7 @@ static void ais_vfe_bus_handle_client_frame_done(
		CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x",
		CAM_DBG(CAM_ISP, "IFE%d BUF| RDI%d DQ %d (0x%x) FIFO:%d|0x%x",
			core_info->vfe_idx, path,
			core_info->vfe_idx, path,
			vfe_buf->bufIdx, vfe_buf->iova_addr,
			vfe_buf->bufIdx, vfe_buf->iova_addr,
			rdi_path->num_buffer_hw_q, rdi_path->last_addr);
			rdi_path->num_buffer_hw_q, last_addr);


		core_info->event.type = AIS_IFE_MSG_FRAME_DONE;
		core_info->event.type = AIS_IFE_MSG_FRAME_DONE;
		core_info->event.path = path;
		core_info->event.path = path;
@@ -937,15 +950,18 @@ static void ais_vfe_bus_handle_client_frame_done(
		core_info->event_cb(core_info->event_cb_priv,
		core_info->event_cb(core_info->event_cb_priv,
				&core_info->event);
				&core_info->event);


		if (rdi_path->last_addr == vfe_buf->iova_addr)
		if (last_addr == vfe_buf->iova_addr)
			last_addr_match = true;
			last_addr_match = true;
		else
			CAM_WARN(CAM_ISP, "IFE%d buf %d did not match addr",
				core_info->vfe_idx, vfe_buf->bufIdx);


		list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list);
		list_add_tail(&vfe_buf->list, &rdi_path->free_buffer_list);
	}
	}


	if (!last_addr_match)
	if (!last_addr_match)
		CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x",
		CAM_ERR(CAM_ISP, "IFE%d BUF| RDI%d NO MATCH addr 0x%x",
			core_info->vfe_idx, path, rdi_path->last_addr);
			core_info->vfe_idx, path, last_addr);


	ais_vfe_queue_to_hw(core_info, path);
	ais_vfe_queue_to_hw(core_info, path);


@@ -954,9 +970,10 @@ static void ais_vfe_bus_handle_client_frame_done(


static int ais_vfe_bus_handle_frame_done(
static int ais_vfe_bus_handle_frame_done(
	struct ais_vfe_hw_core_info *core_info,
	struct ais_vfe_hw_core_info *core_info,
	uint32_t client_mask)
	struct ais_vfe_hw_work_data *work_data)
{
{
	struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0];
	struct ais_vfe_rdi_output *p_rdi = &core_info->rdi_out[0];
	uint32_t client_mask = work_data->bus_wr_status[1];
	uint32_t client;
	uint32_t client;
	int rc = 0;
	int rc = 0;


@@ -971,19 +988,18 @@ static int ais_vfe_bus_handle_frame_done(


		if (client_mask & (0x1 << client)) {
		if (client_mask & (0x1 << client)) {
			//process frame done
			//process frame done
			ais_vfe_bus_handle_client_frame_done(core_info, client);
			ais_vfe_bus_handle_client_frame_done(core_info,
				client, work_data->last_addr[client]);
		}
		}
	}
	}


	return rc;
	return rc;
}
}


static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw,
static void ais_vfe_irq_fill_bus_wr_status(
	struct ais_vfe_hw_core_info *core_info,
	struct ais_vfe_hw_core_info *core_info,
	struct ais_vfe_hw_work_data *work_data)
	struct ais_vfe_hw_work_data *work_data)
{
{
	int rc = 0;
	uint32_t vfe_bus_status[3] = {};
	struct ais_vfe_bus_ver2_hw_info   *bus_hw_info = NULL;
	struct ais_vfe_bus_ver2_hw_info   *bus_hw_info = NULL;
	struct ais_irq_register_set       *bus_hw_irq_regs = NULL;
	struct ais_irq_register_set       *bus_hw_irq_regs = NULL;
	struct ais_vfe_bus_ver2_reg_offset_bus_client  *client_regs = NULL;
	struct ais_vfe_bus_ver2_reg_offset_bus_client  *client_regs = NULL;
@@ -993,53 +1009,72 @@ static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw,
	bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set;
	bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set;
	client_regs = &bus_hw_info->bus_client_reg[client];
	client_regs = &bus_hw_info->bus_client_reg[client];


	vfe_bus_status[0] = cam_io_r_mb(core_info->mem_base +
	work_data->bus_wr_status[0] = cam_io_r_mb(core_info->mem_base +
		bus_hw_irq_regs[0].status_reg_offset);
		bus_hw_irq_regs[0].status_reg_offset);
	vfe_bus_status[1] = cam_io_r_mb(core_info->mem_base +
	work_data->bus_wr_status[1] = cam_io_r_mb(core_info->mem_base +
		bus_hw_irq_regs[1].status_reg_offset);
		bus_hw_irq_regs[1].status_reg_offset);
	vfe_bus_status[2] = cam_io_r_mb(core_info->mem_base +
	work_data->bus_wr_status[2] = cam_io_r_mb(core_info->mem_base +
		bus_hw_irq_regs[2].status_reg_offset);
		bus_hw_irq_regs[2].status_reg_offset);


	if (vfe_bus_status[1]) {
	if (work_data->bus_wr_status[1]) {
		struct ais_vfe_rdi_output *p_rdi;
		struct ais_vfe_rdi_output *p_rdi;


		for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) {
		for (client = 0 ; client < AIS_IFE_PATH_MAX; client++) {
			if (vfe_bus_status[1] & (0x1 << client)) {
			if (work_data->bus_wr_status[1] & (0x1 << client)) {
				p_rdi = &core_info->rdi_out[client];
				p_rdi = &core_info->rdi_out[client];
				client_regs =
				client_regs =
					&bus_hw_info->bus_client_reg[client];
					&bus_hw_info->bus_client_reg[client];
				p_rdi->last_addr = cam_io_r(
				work_data->last_addr[client] = cam_io_r(
					core_info->mem_base +
					core_info->mem_base +
					client_regs->status0);
					client_regs->status0);
			}
			}
		}
		}
	}
	}


	cam_io_w(vfe_bus_status[0], core_info->mem_base +
	cam_io_w(work_data->bus_wr_status[0], core_info->mem_base +
		bus_hw_irq_regs[0].clear_reg_offset);
		bus_hw_irq_regs[0].clear_reg_offset);
	cam_io_w(vfe_bus_status[1], core_info->mem_base +
	cam_io_w(work_data->bus_wr_status[1], core_info->mem_base +
		bus_hw_irq_regs[1].clear_reg_offset);
		bus_hw_irq_regs[1].clear_reg_offset);
	cam_io_w(vfe_bus_status[2], core_info->mem_base +
	cam_io_w(work_data->bus_wr_status[2], core_info->mem_base +
		bus_hw_irq_regs[2].clear_reg_offset);
		bus_hw_irq_regs[2].clear_reg_offset);
	cam_io_w_mb(0x1, core_info->mem_base +
	cam_io_w_mb(0x1, core_info->mem_base +
		bus_hw_info->common_reg.irq_reg_info.global_clear_offset);
		bus_hw_info->common_reg.irq_reg_info.global_clear_offset);
}

static int ais_vfe_handle_bus_wr_irq(struct cam_hw_info *vfe_hw,
	struct ais_vfe_hw_core_info *core_info,
	struct ais_vfe_hw_work_data *work_data)
{
	int rc = 0;
	struct ais_vfe_bus_ver2_hw_info   *bus_hw_info = NULL;
	struct ais_irq_register_set       *bus_hw_irq_regs = NULL;
	struct ais_vfe_bus_ver2_reg_offset_bus_client  *client_regs = NULL;
	uint32_t client = 0;

	bus_hw_info = core_info->vfe_hw_info->bus_hw_info;
	bus_hw_irq_regs = bus_hw_info->common_reg.irq_reg_info.irq_reg_set;
	client_regs = &bus_hw_info->bus_client_reg[client];



	CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx,
	CAM_DBG(CAM_ISP, "VFE%d BUS status 0x%x 0x%x 0x%x", core_info->vfe_idx,
		vfe_bus_status[0], vfe_bus_status[1], vfe_bus_status[2]);
		work_data->bus_wr_status[0],
		work_data->bus_wr_status[1],
		work_data->bus_wr_status[2]);


	if (vfe_bus_status[1])
	if (work_data->bus_wr_status[1])
		ais_vfe_bus_handle_frame_done(core_info, vfe_bus_status[1]);
		ais_vfe_bus_handle_frame_done(core_info, work_data);


	if (vfe_bus_status[0] & 0x7800)	{
	if (work_data->bus_wr_status[0] & 0x7800) {
		CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x",
		CAM_ERR(CAM_ISP, "VFE%d: WR BUS error occurred status = 0x%x",
			core_info->vfe_idx, vfe_bus_status[0]);
			core_info->vfe_idx, work_data->bus_wr_status[0]);
		work_data->path = (vfe_bus_status[0] >> 11) & 0xF;
		work_data->path = (work_data->bus_wr_status[0] >> 11) & 0xF;
		rc = ais_vfe_handle_error(core_info, work_data);
		rc = ais_vfe_handle_error(core_info, work_data);
	}
	}


	if (vfe_bus_status[0] & 0x1) {
	if (work_data->bus_wr_status[0] & 0x1) {
		CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed",
		CAM_INFO(CAM_ISP, "VFE%d: WR BUS reset completed",
			core_info->vfe_idx);
			core_info->vfe_idx);
		complete(&vfe_hw->hw_complete);
	}
	}


	return rc;
	return rc;
@@ -1194,6 +1229,7 @@ irqreturn_t ais_vfe_irq(int irq_num, void *data)
			//BUS_WR IRQ
			//BUS_WR IRQ
			CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx);
			CAM_DBG(CAM_ISP, "IFE%d BUS_WR", core_info->vfe_idx);
			work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR;
			work_data.evt_type = AIS_VFE_HW_IRQ_EVENT_BUS_WR;
			ais_vfe_irq_fill_bus_wr_status(core_info, &work_data);
			ais_vfe_dispatch_irq(vfe_hw, &work_data);
			ais_vfe_dispatch_irq(vfe_hw, &work_data);
		}
		}
		if (ife_status[1]) {
		if (ife_status[1]) {
+2 −1
Original line number Original line Diff line number Diff line
@@ -40,6 +40,8 @@ struct ais_vfe_hw_work_data {
	enum ais_vfe_hw_irq_event evt_type;
	enum ais_vfe_hw_irq_event evt_type;
	uint32_t           path;
	uint32_t           path;
	uint64_t           ts;
	uint64_t           ts;
	uint32_t           bus_wr_status[3];
	uint32_t           last_addr[AIS_IFE_PATH_MAX];
	struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX];
	struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX];
};
};


@@ -93,7 +95,6 @@ struct ais_vfe_rdi_output {
	struct list_head                 buffer_hw_q;
	struct list_head                 buffer_hw_q;
	struct list_head                 free_buffer_list;
	struct list_head                 free_buffer_list;


	uint32_t                         last_addr;
	uint64_t                         frame_cnt;
	uint64_t                         frame_cnt;
	uint64_t                         sof_ts;
	uint64_t                         sof_ts;
	uint64_t                         sof_hw_ts;
	uint64_t                         sof_hw_ts;
+2 −1
Original line number Original line Diff line number Diff line
@@ -417,7 +417,8 @@ int cam_vfe_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size)
		reset_core_args, arg_size);
		reset_core_args, arg_size);
	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
	/* Wait for Completion or Timeout of 500ms */
	/* Wait for Completion or Timeout of 500ms */
	rc = wait_for_completion_timeout(&vfe_hw->hw_complete, 500);
	rc = wait_for_completion_timeout(&vfe_hw->hw_complete,
					msecs_to_jiffies(500));
	if (!rc)
	if (!rc)
		CAM_ERR(CAM_ISP, "Error! Reset Timeout");
		CAM_ERR(CAM_ISP, "Error! Reset Timeout");