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

Commit eacc6fd8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Fix composite stats irq handling"

parents 7f767df7 b9861f1c
Loading
Loading
Loading
Loading
+119 −78
Original line number Original line Diff line number Diff line
@@ -67,78 +67,31 @@ buf_error:
	return rc;
	return rc;
}
}


void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1,
	struct msm_isp_buffer *done_buf, struct msm_isp_timestamp *ts,
	struct msm_isp_timestamp *ts)
	struct msm_isp_event_data *buf_event,
	struct msm_vfe_stats_stream *stream_info,
	uint32_t *comp_stats_type_mask)
{
{
	int i, j, rc;
	int32_t rc = 0;
	struct msm_isp_event_data buf_event;
	struct msm_isp_stats_event *stats_event = NULL;
	struct msm_isp_stats_event *stats_event = &buf_event.u.stats;

	struct msm_isp_buffer *done_buf;
	if (!vfe_dev || !done_buf || !ts || !buf_event || !stream_info ||
	struct msm_vfe_stats_stream *stream_info = NULL;
		!comp_stats_type_mask) {
	uint32_t pingpong_status;
		pr_err("%s:%d failed: invalid params %p %p %p %p %p %p\n",
	uint32_t comp_stats_type_mask = 0, atomic_stats_mask = 0;
			__func__, __LINE__, vfe_dev, done_buf, ts, buf_event,
	uint32_t stats_comp_mask = 0, stats_irq_mask = 0;
			stream_info, comp_stats_type_mask);
	uint32_t num_stats_comp_mask =
		return -EINVAL;
		vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;
	stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
		get_comp_mask(irq_status0, irq_status1);
	stats_irq_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
		get_wm_mask(irq_status0, irq_status1);
	if (!(stats_comp_mask || stats_irq_mask))
		return;
	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);

	/*
	 * If any of composite mask is set, clear irq bits from mask,
	 * they will be restored by comp mask
	 */
	if (stats_comp_mask) {
		for (j = 0; j < num_stats_comp_mask; j++) {
			stats_irq_mask &= ~atomic_read(
				&vfe_dev->stats_data.stats_comp_mask[j]);
		}
	}

	for (j = 0; j < num_stats_comp_mask; j++) {
		atomic_stats_mask = atomic_read(
			&vfe_dev->stats_data.stats_comp_mask[j]);
		if (!stats_comp_mask) {
			stats_irq_mask &= ~atomic_stats_mask;
		} else {
			/* restore irq bits from composite mask */
			if (stats_comp_mask & (1 << j))
				stats_irq_mask |= atomic_stats_mask;
	}
	}
		/* if no irq bits set from this composite mask continue*/
		if (!stats_irq_mask)
			continue;
		memset(&buf_event, 0, sizeof(struct msm_isp_event_data));
		buf_event.timestamp = ts->event_time;
		buf_event.frame_id =
			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
		buf_event.input_intf = VFE_PIX_0;
		pingpong_status = vfe_dev->hw_info->
			vfe_ops.stats_ops.get_pingpong_status(vfe_dev);

		for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type;
			i++) {
			if (!(stats_irq_mask & (1 << i)))
				continue;


			stats_irq_mask &= ~(1 << i);
	stats_event = &buf_event->u.stats;
			stream_info = &vfe_dev->stats_data.stream_info[i];
			done_buf = NULL;
			msm_isp_stats_cfg_ping_pong_address(vfe_dev,
				stream_info, pingpong_status, &done_buf);
			if (done_buf) {
	rc = vfe_dev->buf_mgr->ops->buf_divert(
	rc = vfe_dev->buf_mgr->ops->buf_divert(
		vfe_dev->buf_mgr, done_buf->bufq_handle,
		vfe_dev->buf_mgr, done_buf->bufq_handle,
		done_buf->buf_idx, &ts->buf_time,
		done_buf->buf_idx, &ts->buf_time,
		vfe_dev->axi_data.
		vfe_dev->axi_data.
		src_info[VFE_PIX_0].frame_id);
		src_info[VFE_PIX_0].frame_id);
	if (rc != 0)
	if (rc != 0)
					continue;
		return rc;


	stats_event->stats_buf_idxs
	stats_event->stats_buf_idxs
		[stream_info->stats_type] =
		[stream_info->stats_type] =
@@ -147,16 +100,53 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
		stats_event->stats_mask =
		stats_event->stats_mask =
			1 << stream_info->stats_type;
			1 << stream_info->stats_type;
		ISP_DBG("%s: stats frameid: 0x%x %d\n",
		ISP_DBG("%s: stats frameid: 0x%x %d\n",
						__func__, buf_event.frame_id,
			__func__, buf_event->frame_id,
			stream_info->stats_type);
			stream_info->stats_type);
		msm_isp_send_event(vfe_dev,
		msm_isp_send_event(vfe_dev,
			ISP_EVENT_STATS_NOTIFY +
			ISP_EVENT_STATS_NOTIFY +
			stream_info->stats_type,
			stream_info->stats_type,
						&buf_event);
			buf_event);
	} else {
	} else {
					comp_stats_type_mask |=
		*comp_stats_type_mask |=
			1 << stream_info->stats_type;
			1 << stream_info->stats_type;
	}
	}

	return 0;
}

static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
	uint32_t stats_irq_mask, struct msm_isp_timestamp *ts)
{
	int i, rc = 0;
	struct msm_isp_event_data buf_event;
	struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
	struct msm_isp_buffer *done_buf;
	struct msm_vfe_stats_stream *stream_info = NULL;
	uint32_t pingpong_status;
	uint32_t comp_stats_type_mask = 0;

	memset(&buf_event, 0, sizeof(struct msm_isp_event_data));
	buf_event.timestamp = ts->event_time;
	buf_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
	buf_event.input_intf = VFE_PIX_0;
	pingpong_status = vfe_dev->hw_info->
		vfe_ops.stats_ops.get_pingpong_status(vfe_dev);

	for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
		if (!(stats_irq_mask & (1 << i)))
			continue;

		stream_info = &vfe_dev->stats_data.stream_info[i];
		done_buf = NULL;
		msm_isp_stats_cfg_ping_pong_address(vfe_dev,
			stream_info, pingpong_status, &done_buf);
		if (done_buf) {
			rc = msm_isp_stats_buf_divert(vfe_dev, done_buf, ts,
				&buf_event, stream_info, &comp_stats_type_mask);
			if (rc < 0) {
				pr_err("%s:%d failed: stats buf divert rc %d\n",
					__func__, __LINE__, rc);
			}
		}
		}
	}
	}


@@ -169,6 +159,57 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
			ISP_EVENT_COMP_STATS_NOTIFY, &buf_event);
			ISP_EVENT_COMP_STATS_NOTIFY, &buf_event);
		comp_stats_type_mask = 0;
		comp_stats_type_mask = 0;
	}
	}
	return rc;
}

void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
	uint32_t irq_status0, uint32_t irq_status1,
	struct msm_isp_timestamp *ts)
{
	int j, rc;
	uint32_t atomic_stats_mask = 0;
	uint32_t stats_comp_mask = 0, stats_irq_mask = 0;
	uint32_t num_stats_comp_mask =
		vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;
	stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
		get_comp_mask(irq_status0, irq_status1);
	stats_irq_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
		get_wm_mask(irq_status0, irq_status1);
	if (!(stats_comp_mask || stats_irq_mask))
		return;
	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);

	/* Clear composite mask irq bits, they will be restored by comp mask */
	for (j = 0; j < num_stats_comp_mask; j++) {
		stats_irq_mask &= ~atomic_read(
			&vfe_dev->stats_data.stats_comp_mask[j]);
	}

	/* Process non-composite irq */
	if (stats_irq_mask) {
		rc = msm_isp_stats_configure(vfe_dev, stats_irq_mask, ts);
		if (rc < 0) {
			pr_err("%s:%d failed individual stats rc %d\n",
				__func__, __LINE__, rc);
		}
	}

	/* Process composite irq */
	if (stats_comp_mask) {
		for (j = 0; j < num_stats_comp_mask; j++) {
			if (!(stats_comp_mask & (1 << j)))
				continue;

			atomic_stats_mask = atomic_read(
				&vfe_dev->stats_data.stats_comp_mask[j]);

			rc = msm_isp_stats_configure(vfe_dev, atomic_stats_mask,
				ts);
			if (rc < 0) {
				pr_err("%s:%d failed comp stats %d rc %d\n",
					__func__, __LINE__, j, rc);
			}
		}
	}
	}
}
}