lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4f7abad9943b070095728a115093a019d6bff13b.camel@mediatek.com>
Date: Mon, 21 Jul 2025 01:40:13 +0000
From: CK Hu (胡俊光) <ck.hu@...iatek.com>
To: "robh@...nel.org" <robh@...nel.org>, "mchehab@...nel.org"
	<mchehab@...nel.org>, "krzk+dt@...nel.org" <krzk+dt@...nel.org>,
	"conor+dt@...nel.org" <conor+dt@...nel.org>, "matthias.bgg@...il.com"
	<matthias.bgg@...il.com>, Shangyao Lin (林上堯)
	<Shangyao.Lin@...iatek.com>, AngeloGioacchino Del Regno
	<angelogioacchino.delregno@...labora.com>
CC: "linux-media@...r.kernel.org" <linux-media@...r.kernel.org>,
	"linaro-mm-sig@...ts.linaro.org" <linaro-mm-sig@...ts.linaro.org>,
	Project_Global_Chrome_Upstream_Group
	<Project_Global_Chrome_Upstream_Group@...iatek.com>,
	"devicetree@...r.kernel.org" <devicetree@...r.kernel.org>,
	"dri-devel@...ts.freedesktop.org" <dri-devel@...ts.freedesktop.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"linux-arm-kernel@...ts.infradead.org"
	<linux-arm-kernel@...ts.infradead.org>, "linux-mediatek@...ts.infradead.org"
	<linux-mediatek@...ts.infradead.org>
Subject: Re: [PATCH v2 06/13] media: platform: mediatek: add isp_7x state ctrl

On Mon, 2025-07-07 at 09:31 +0800, shangyao lin wrote:
> From: "shangyao.lin" <shangyao.lin@...iatek.com>
> 
> Introduce state management and debugging mechanisms for the MediaTek ISP7.x
> camsys platform. State management establishes control over ISP operations and
> events, defining distinct states for request handling, sensor control, and
> frame synchronization, ensuring proper event processing. The debugging
> mechanism ensures stable operation and timely data collection during anomalies.
> 
> ---
> 
> Changes in v2:
> - Removed mtk_cam-debug.c and mtk_cam-debug.h, along with related code
> - Various fixes per review comments
> 
> Signed-off-by: shangyao.lin <shangyao.lin@...iatek.com>
> ---
>  .../mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.c | 1409 +++++++++++++++++
>  .../mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.h |  131 ++
>  2 files changed, 1540 insertions(+)
>  create mode 100755 drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.c

Why this file is executable?

>  create mode 100755 drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.h

Ditto.

> 
> diff --git a/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.c b/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.c
> new file mode 100755
> index 000000000000..15af1eac5444
> --- /dev/null
> +++ b/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_cam-ctrl.c
> @@ -0,0 +1,1409 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.

2025

> + */
> +
> +#include <linux/list.h>
> +#include <linux/math64.h>
> +#include <linux/of.h>
> +#include <linux/videodev2.h>
> +#include <linux/hrtimer.h>

Alphabetic order.

> +
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-ioctl.h>

Alphabetic order.

> +
> +#include "mtk_cam.h"
> +#include "mtk_cam-ctrl.h"
> +#include "mtk_cam-pool.h"
> +#include "mtk_cam-raw.h"
> +

Drop this blank line.

> +#include "mtk_cam-regs-mt8188.h"
> +

Drop this blank line.

> +#include "mtk_camera-v4l2-controls.h"
> +
> +#define SENSOR_SET_DEADLINE_MS  18
> +#define SENSOR_SET_RESERVED_MS  7
> +#define SENSOR_SET_DEADLINE_MS_60FPS  6
> +#define SENSOR_SET_RESERVED_MS_60FPS  6
> +#define STATE_NUM_AT_SOF 3
> +#define INITIAL_DROP_FRAME_CNT 1
> +
> +enum MTK_CAMSYS_STATE_RESULT {
> +	STATE_RESULT_TRIGGER_CQ = 0,
> +	STATE_RESULT_PASS_CQ_INIT,
> +	STATE_RESULT_PASS_CQ_SW_DELAY,
> +	STATE_RESULT_PASS_CQ_SCQ_DELAY,
> +	STATE_RESULT_PASS_CQ_HW_DELAY,

After call mtk_camsys_raw_state_handle(), just check STATE_RESULT_TRIGGER_CQ or not.
There result is just for print error log.
Direct print error in mtk_camsys_raw_state_handle() and drop these definition.

> +};
> +
> +void state_transition(struct mtk_camsys_ctrl_state *state_entry,

static void state_transition(struct mtk_camsys_ctrl_state *state_entry,

> +		      enum MTK_CAMSYS_STATE_IDX from,
> +		      enum MTK_CAMSYS_STATE_IDX to)
> +{
> +	if (state_entry->estate == from)
> +		state_entry->estate = to;
> +}
> +

[snip]

> +void mtk_cam_set_sensor_full(struct mtk_cam_request_stream_data *s_data,
> +			     struct mtk_camsys_sensor_ctrl *sensor_ctrl)
> +{
> +	struct mtk_cam_device *cam;
> +	struct mtk_cam_ctx *ctx;
> +	struct mtk_cam_request *req;
> +	struct mtk_raw_device *raw_dev;
> +	unsigned int time_after_sof = 0;
> +
> +	/* EnQ this request's state element to state_list (STATE:READY) */
> +	spin_lock(&sensor_ctrl->camsys_state_lock);
> +	list_add_tail(&s_data->state.state_element,
> +		      &sensor_ctrl->camsys_state_list);
> +	atomic_set(&sensor_ctrl->sensor_request_seq_no, s_data->frame_seq_no);
> +	spin_unlock(&sensor_ctrl->camsys_state_lock);
> +
> +	/* sensor_worker task */
> +	ctx = mtk_cam_s_data_get_ctx(s_data);
> +	cam = ctx->cam;
> +	req = mtk_cam_s_data_get_req(s_data);
> +
> +	dev_dbg(cam->dev, "%s:%s:ctx(%d) req(%d):sensor try set start\n",
> +		__func__, req->req.debug_str, ctx->stream_id, s_data->frame_seq_no);
> +
> +	if (ctx->used_raw_num && mtk_cam_req_frame_sync_start(req))
> +		dev_dbg(cam->dev,
> +			"%s:%s:ctx(%d): sensor ctrl with frame sync - start\n",
> +			__func__, req->req.debug_str, ctx->stream_id);
> +
> +	/*
> +	 * request setup
> +	 * 1st frame sensor setting is treated like normal frame
> +	 * and is set with other settings like max fps.
> +	 * 2nd is special, only exposure is set.
> +	 */
> +	if (s_data->flags & MTK_CAM_REQ_S_DATA_FLAG_SENSOR_HDL_EN) {

In patch [8/13] I says ctx->sensor is always NULL, and MTK_CAM_REQ_S_DATA_FLAG_SENSOR_HDL_EN is set only when ctx->sensor is not NULL.
So drop MTK_CAM_REQ_S_DATA_FLAG_SENSOR_HDL_EN.

> +		v4l2_ctrl_request_setup(&req->req,
> +					s_data->sensor->ctrl_handler);
> +		time_after_sof =
> +			div_u64(ktime_get_boottime_ns(), 1000000) -
> +				ctx->sensor_ctrl.sof_time;
> +		dev_dbg(cam->dev,
> +			"[SOF+%dms] Sensor request:%d[ctx:%d] setup\n",
> +			time_after_sof, s_data->frame_seq_no,
> +			ctx->stream_id);
> +	}
> +
> +	state_transition(&s_data->state, E_STATE_READY, E_STATE_SENSOR);
> +
> +	if (ctx->used_raw_num && mtk_cam_req_frame_sync_end(req))
> +		dev_dbg(cam->dev,
> +			"%s:ctx(%d): sensor ctrl with frame sync - stop\n",
> +			__func__, ctx->stream_id);
> +
> +	if (ctx->used_raw_num) {
> +		raw_dev = get_main_raw_dev(ctx->cam, ctx->pipe);
> +		if (raw_dev && atomic_read(&raw_dev->vf_en) == 0 &&
> +		    ctx->sensor_ctrl.initial_cq_done == 1 &&
> +		    s_data->frame_seq_no == 1)
> +			mtk_cam_stream_on(raw_dev, ctx);
> +	}
> +
> +	dev_dbg(cam->dev, "%s:%s:ctx(%d)req(%d):sensor done at SOF+%dms\n",
> +		__func__, req->req.debug_str, ctx->stream_id,
> +		s_data->frame_seq_no, time_after_sof);
> +
> +	mtk_cam_complete_sensor_hdl(s_data);
> +}
> +

[snip]

> +static int
> +mtk_camsys_raw_state_handle(struct mtk_raw_device *raw_dev,
> +			    struct mtk_camsys_sensor_ctrl *sensor_ctrl,
> +			    struct mtk_camsys_ctrl_state **current_state,
> +			    struct mtk_camsys_irq_info *irq_info)
> +{
> +	struct mtk_cam_ctx *ctx = sensor_ctrl->ctx;
> +	struct mtk_camsys_ctrl_state *state_temp, *state_outer = NULL;
> +	struct mtk_camsys_ctrl_state *state_inner = NULL;
> +	struct mtk_camsys_ctrl_state *state_rec[STATE_NUM_AT_SOF];
> +	struct mtk_cam_request_stream_data *req_stream_data;
> +	int frame_idx_inner = irq_info->frame_idx_inner;
> +	int stateidx;
> +	int que_cnt = 0;
> +	int write_cnt;
> +	u64 time_boot = ktime_get_boottime_ns();
> +	u64 time_mono = ktime_get_ns();
> +	int working_req_found = 0;
> +
> +	/* List state-queue status*/
> +	spin_lock(&sensor_ctrl->camsys_state_lock);
> +	list_for_each_entry(state_temp, &sensor_ctrl->camsys_state_list,
> +			    state_element) {
> +		req_stream_data = mtk_cam_ctrl_state_to_req_s_data(state_temp);
> +		stateidx = atomic_read(&sensor_ctrl->sensor_request_seq_no) -
> +			   req_stream_data->frame_seq_no;
> +		if (stateidx < STATE_NUM_AT_SOF && stateidx > -1) {
> +			state_rec[stateidx] = state_temp;
> +			if (stateidx == 0)
> +				working_req_found = 1;
> +
> +			/* Find outer state element */
> +			if (state_temp->estate == E_STATE_OUTER ||
> +			    state_temp->estate == E_STATE_CAMMUX_OUTER ||
> +			    state_temp->estate == E_STATE_OUTER_HW_DELAY) {
> +				state_outer = state_temp;
> +				mtk_cam_set_timestamp(req_stream_data,
> +						      time_boot, time_mono);
> +			}
> +
> +			/* Find inner state element request */
> +			if (state_temp->estate == E_STATE_INNER ||
> +			    state_temp->estate == E_STATE_INNER_HW_DELAY)
> +				state_inner = state_temp;
> +
> +			dev_dbg(raw_dev->dev,
> +				"[SOF] STATE_CHECK [N-%d] Req:%d / State:%d\n",
> +				stateidx, req_stream_data->frame_seq_no,
> +				state_rec[stateidx]->estate);
> +		}
> +		/* counter for state queue*/
> +		que_cnt++;
> +	}
> +	spin_unlock(&sensor_ctrl->camsys_state_lock);
> +
> +	/* HW imcomplete case */
> +	if (state_inner) {
> +		req_stream_data = mtk_cam_ctrl_state_to_req_s_data(state_inner);
> +		write_cnt = (atomic_read(&sensor_ctrl->isp_request_seq_no) / 256)
> +					* 256 + irq_info->write_cnt;
> +
> +		if (frame_idx_inner > atomic_read(&sensor_ctrl->isp_request_seq_no) ||
> +		    atomic_read(&req_stream_data->frame_done_work.is_queued) == 1) {
> +			dev_dbg_ratelimited(raw_dev->dev,
> +					    "[SOF] frame done work too late frames. req(%d),ts(%llu)\n",
> +					    req_stream_data->frame_seq_no,
> +					    irq_info->ts_ns);
> +		} else if (write_cnt >= req_stream_data->frame_seq_no) {
> +			dev_info_ratelimited(raw_dev->dev,
> +					     "[SOF] frame done reading lost %d frames. req(%d),ts(%llu)\n",
> +					     write_cnt - req_stream_data->frame_seq_no + 1,
> +					     req_stream_data->frame_seq_no,
> +					     irq_info->ts_ns);
> +			mtk_cam_set_timestamp(req_stream_data,
> +					      time_boot - 1000, time_mono - 1000);
> +			mtk_camsys_frame_done(ctx, write_cnt, ctx->stream_id);
> +		} else if ((write_cnt >= req_stream_data->frame_seq_no - 1) &&
> +			   irq_info->fbc_cnt == 0) {
> +			dev_info_ratelimited(raw_dev->dev,
> +					     "[SOF] frame done reading lost frames. req(%d),ts(%llu)\n",
> +					     req_stream_data->frame_seq_no, irq_info->ts_ns);
> +			mtk_cam_set_timestamp(req_stream_data,
> +					      time_boot - 1000, time_mono - 1000);
> +			mtk_camsys_frame_done(ctx, write_cnt + 1, ctx->stream_id);
> +		} else {
> +			state_transition(state_inner,
> +					 E_STATE_INNER, E_STATE_INNER_HW_DELAY);
> +			if (state_outer) {
> +				state_transition(state_outer,
> +						 E_STATE_OUTER,
> +						 E_STATE_OUTER_HW_DELAY);
> +				state_transition(state_outer,
> +						 E_STATE_CAMMUX_OUTER,
> +						 E_STATE_OUTER_HW_DELAY);
> +			}
> +			dev_info_ratelimited(raw_dev->dev,
> +					     "[SOF] HW_IMCOMPLETE state cnt(%d,%d),req(%d),ts(%llu)\n",
> +					     write_cnt, irq_info->write_cnt,
> +					     req_stream_data->frame_seq_no,
> +					     irq_info->ts_ns);
> +			return STATE_RESULT_PASS_CQ_HW_DELAY;
> +		}
> +	}
> +
> +	/* Transit outer state to inner state */
> +	if (state_outer && sensor_ctrl->sensorsetting_wq) {
> +		req_stream_data = mtk_cam_ctrl_state_to_req_s_data(state_outer);
> +		if (atomic_read(&sensor_ctrl->initial_drop_frame_cnt) == 0 &&
> +		    req_stream_data->frame_seq_no > frame_idx_inner) {
> +			dev_info(raw_dev->dev,
> +				 "[SOF-noDBLOAD] HW delay outer_no:%d, inner_idx:%d <= processing_idx:%d,ts:%llu\n",
> +				 req_stream_data->frame_seq_no, frame_idx_inner,
> +				 atomic_read(&sensor_ctrl->isp_request_seq_no),
> +				 irq_info->ts_ns);
> +			return STATE_RESULT_PASS_CQ_HW_DELAY;
> +		}
> +
> +		if (atomic_read(&sensor_ctrl->initial_drop_frame_cnt) == 0 &&
> +		    req_stream_data->frame_seq_no == frame_idx_inner) {
> +			if (frame_idx_inner >
> +			    atomic_read(&sensor_ctrl->isp_request_seq_no)) {
> +				state_transition(state_outer,
> +						 E_STATE_OUTER_HW_DELAY,
> +						 E_STATE_INNER_HW_DELAY);
> +				state_transition(state_outer,
> +						 E_STATE_OUTER,
> +						 E_STATE_INNER);
> +				state_transition(state_outer,
> +						 E_STATE_CAMMUX_OUTER,
> +						 E_STATE_INNER);

State would change to E_STATE_INNER only in mtk_camsys_raw_state_handle().
mtk_camsys_raw_state_handle() is called only when ctx->sensor is not NULL.
In patch [8/13] I say ctx-sensor is always NULL,
so state would never change to E_STATE_INNER.
Drop it.

> +				atomic_set(&sensor_ctrl->isp_request_seq_no, frame_idx_inner);
> +				dev_dbg(raw_dev->dev,
> +					"[SOF-DBLOAD] frame_seq_no:%d, OUTER->INNER state:%d,ts:%llu\n",
> +					req_stream_data->frame_seq_no,
> +					state_outer->estate, irq_info->ts_ns);
> +			}
> +		}
> +	}
> +
> +	/* Trigger high resolution timer to try sensor setting */
> +	sensor_ctrl->sof_time = div_u64(irq_info->ts_ns, 1000000);
> +	mtk_cam_sof_timer_setup(ctx);
> +
> +	if (que_cnt > 1 && state_rec[1]) {
> +		state_temp = state_rec[1];
> +		req_stream_data = mtk_cam_ctrl_state_to_req_s_data(state_temp);
> +		if (req_stream_data->frame_seq_no == 1)
> +			state_transition(state_temp,
> +					 E_STATE_SENSOR, E_STATE_INNER);
> +	}
> +
> +	if (que_cnt > 0) {
> +		if (working_req_found && state_rec[0]) {
> +			if (state_rec[0]->estate == E_STATE_READY) {
> +				dev_info(raw_dev->dev, "[SOF] sensor delay ts:%llu\n",
> +					 irq_info->ts_ns);
> +				req_stream_data =
> +					mtk_cam_ctrl_state_to_req_s_data(state_rec[0]);
> +				req_stream_data->flags |=
> +					MTK_CAM_REQ_S_DATA_FLAG_SENSOR_HDL_DELAYED;
> +			}
> +
> +			if (state_rec[0]->estate == E_STATE_SENINF)
> +				dev_info(raw_dev->dev, "[SOF] sensor switch delay\n");
> +
> +			/* CQ triggering judgment*/
> +			if (state_rec[0]->estate == E_STATE_SENSOR) {
> +				*current_state = state_rec[0];
> +				return STATE_RESULT_TRIGGER_CQ;
> +			}
> +			/* last SCQ triggering delay judgment*/
> +			if (state_rec[0]->estate == E_STATE_CQ_SCQ_DELAY) {
> +				state_transition(state_rec[0],
> +						 E_STATE_CQ_SCQ_DELAY,
> +						 E_STATE_OUTER);
> +				dev_info(raw_dev->dev, "[SOF] SCQ_DELAY state:%d ts:%llu\n",
> +					 state_rec[0]->estate, irq_info->ts_ns);
> +				return STATE_RESULT_PASS_CQ_SCQ_DELAY;
> +			}
> +		} else {
> +			dev_dbg(raw_dev->dev, "[SOF] working request not found\n");
> +		}
> +	}
> +	return STATE_RESULT_PASS_CQ_SW_DELAY;
> +}
> +
> +static void mtk_camsys_raw_frame_start(struct mtk_raw_device *raw_dev,
> +				       struct mtk_cam_ctx *ctx,
> +				       struct mtk_camsys_irq_info *irq_info)
> +{
> +	unsigned int dequeued_frame_seq_no = irq_info->frame_idx_inner;
> +	struct mtk_cam_request_stream_data *req_stream_data;
> +	struct mtk_camsys_sensor_ctrl *sensor_ctrl = &ctx->sensor_ctrl;
> +	struct mtk_cam_working_buf_entry *buf_entry;
> +	struct mtk_camsys_ctrl_state *current_state;
> +	struct mtk_cam_buffer *buf;
> +
> +	dma_addr_t base_addr;
> +	enum MTK_CAMSYS_STATE_RESULT state_handle_ret;
> +
> +	/* touch watchdog*/
> +	if (watchdog_scenario(ctx))

In patch [8/13] I says ctx->sensor is always NULL.
watchdog_scenario() return true only when ctx->sensor is not NULL,
so watchdog_scenario() would always return false.
Drop all watchdog related code.

> +		mtk_ctx_watchdog_kick(ctx);
> +	/* inner register dequeue number */
> +	ctx->dequeued_frame_seq_no = dequeued_frame_seq_no;
> +	/* Send V4L2_EVENT_FRAME_SYNC event */
> +	mtk_cam_event_frame_sync(ctx->pipe, dequeued_frame_seq_no);
> +
> +	/* Handle directly enque buffers */
> +	spin_lock(&ctx->cam->dma_processing_lock);
> +	list_for_each_entry(buf, &ctx->cam->dma_processing, list) {
> +		if (buf->state.estate == E_BUF_STATE_COMPOSED) {
> +			spin_unlock(&ctx->cam->dma_processing_lock);
> +			goto apply_cq;
> +		}
> +	}
> +	spin_unlock(&ctx->cam->dma_processing_lock);
> +	buf = NULL;
> +	current_state = NULL;
> +
> +	/* Find request of this dequeued frame */
> +	req_stream_data =
> +		mtk_cam_get_req_s_data(ctx, ctx->stream_id, dequeued_frame_seq_no);
> +
> +	if (ctx->sensor) {

In patch [8/13] I says ctx->sensor is always NULL, so drop these code.

> +		state_handle_ret =
> +			mtk_camsys_raw_state_handle(raw_dev, sensor_ctrl,
> +						    &current_state, irq_info);

mtk_camsys_raw_state_handle() is called only here, but ctx->sensor is always NULL, so mtk_camsys_raw_state_handle() would never be called.
Drop mtk_camsys_raw_state_handle().

> +
> +		if (state_handle_ret != STATE_RESULT_TRIGGER_CQ) {
> +			dev_dbg(raw_dev->dev, "[SOF] CQ drop s:%d deq:%d\n",
> +				state_handle_ret, dequeued_frame_seq_no);
> +			return;
> +		}
> +	}
> +
> +apply_cq:
> +	/* Update CQ base address if needed */
> +	if (ctx->composed_frame_seq_no <= dequeued_frame_seq_no) {
> +		dev_info_ratelimited(raw_dev->dev,
> +				     "SOF[ctx:%d-#%d], CQ isn't updated [composed_frame_deq (%d) ts:%llu]\n",
> +				     ctx->stream_id, dequeued_frame_seq_no,
> +				     ctx->composed_frame_seq_no, irq_info->ts_ns);
> +		return;
> +	}
> +	/* apply next composed buffer */
> +	spin_lock(&ctx->composed_buffer_list.lock);
> +	if (list_empty(&ctx->composed_buffer_list.list)) {
> +		dev_info_ratelimited(raw_dev->dev,
> +				     "SOF_INT_ST, no buffer update, cq_num:%d, frame_seq:%d, ts:%llu\n",
> +				     ctx->composed_frame_seq_no, dequeued_frame_seq_no,
> +				     irq_info->ts_ns);
> +		spin_unlock(&ctx->composed_buffer_list.lock);
> +	} else {
> +		buf_entry = list_first_entry(&ctx->composed_buffer_list.list,
> +					     struct mtk_cam_working_buf_entry,
> +					     list_entry);
> +		list_del(&buf_entry->list_entry);
> +		ctx->composed_buffer_list.cnt--;
> +		spin_unlock(&ctx->composed_buffer_list.lock);
> +		spin_lock(&ctx->processing_buffer_list.lock);
> +		list_add_tail(&buf_entry->list_entry,
> +			      &ctx->processing_buffer_list.list);
> +		ctx->processing_buffer_list.cnt++;
> +		spin_unlock(&ctx->processing_buffer_list.lock);
> +		base_addr = buf_entry->buffer.iova;
> +		mtk_cam_raw_apply_cq(raw_dev, base_addr,
> +				     buf_entry->cq_desc_size,
> +				     buf_entry->cq_desc_offset,
> +				     buf_entry->sub_cq_desc_size,
> +				     buf_entry->sub_cq_desc_offset);
> +
> +		if (buf) {
> +			buf->state.estate = E_BUF_STATE_CQ;
> +			return;
> +		}
> +
> +		/* Transit state from Sensor -> CQ */
> +		if (ctx->sensor) {
> +			/* req_stream_data of req_cq*/
> +			req_stream_data = mtk_cam_ctrl_state_to_req_s_data(current_state);
> +			state_transition(current_state,
> +					 E_STATE_SENSOR, E_STATE_CQ);

In patch [8/13] I says ctx->sensor is always NULL, so these code would not execute.
This is the only code that change state to E_STATE_CQ but it never execute,
so E_STATE_CQ is useless. Drop it.

> +
> +			dev_dbg(raw_dev->dev,
> +				"SOF[ctx:%d-#%d], CQ-%d is update, composed:%d, cq_addr:0x%pad, time:%lld, monotime:%lld\n",
> +				ctx->stream_id, dequeued_frame_seq_no,
> +				req_stream_data->frame_seq_no,
> +				ctx->composed_frame_seq_no, &base_addr,
> +				req_stream_data->timestamp,
> +				req_stream_data->timestamp_mono);
> +		}
> +	}
> +}
> +

[snip]

> +void mtk_camsys_frame_done(struct mtk_cam_ctx *ctx,
> +			   unsigned int frame_seq_no,
> +			   unsigned int pipe_id)

static void mtk_camsys_frame_done(

> +{
> +	struct mtk_cam_req_work *frame_done_work;
> +	struct mtk_cam_request_stream_data *req_stream_data;
> +	struct mtk_cam_buffer *buf;
> +	struct mtk_cam_working_buf_entry *buf_entry = NULL;
> +	bool is_pending_buffer = false;
> +
> +	spin_lock(&ctx->cam->dma_processing_lock);
> +	if (!list_empty(&ctx->cam->dma_processing)) {
> +		buf = list_first_entry(&ctx->cam->dma_processing,
> +				       struct mtk_cam_buffer, list);
> +		list_del(&buf->list);
> +		ctx->cam->dma_processing_count--;
> +		vb2_buffer_done(&buf->vbb.vb2_buf, VB2_BUF_STATE_DONE);
> +		is_pending_buffer = true;
> +	}
> +	spin_unlock(&ctx->cam->dma_processing_lock);
> +	if (is_pending_buffer) {
> +		spin_lock(&ctx->processing_buffer_list.lock);
> +		if (!list_empty(&ctx->processing_buffer_list.list)) {
> +			buf_entry =
> +				list_first_entry(&ctx->processing_buffer_list.list,
> +						 struct mtk_cam_working_buf_entry,
> +						 list_entry);
> +			list_del(&buf_entry->list_entry);
> +			ctx->processing_buffer_list.cnt--;
> +		}
> +		spin_unlock(&ctx->processing_buffer_list.lock);
> +		if (buf_entry)
> +			mtk_cam_working_buf_put(buf_entry);
> +
> +		mtk_cam_buf_try_queue(ctx);
> +		return;
> +	}
> +
> +	req_stream_data = mtk_cam_get_req_s_data(ctx, pipe_id, frame_seq_no);
> +	if (!req_stream_data) {
> +		dev_err(ctx->cam->dev,
> +			 "%s:ctx-%d:pipe-%d:req(%d) not found!\n",
> +			 __func__, ctx->stream_id, pipe_id, frame_seq_no);
> +		return;
> +	}
> +
> +	if (atomic_read(&req_stream_data->frame_done_work.is_queued)) {
> +		dev_info(ctx->cam->dev,
> +			 "already queue done work req:%d seq:%d pipe_id:%d\n",
> +			 req_stream_data->frame_seq_no, frame_seq_no, pipe_id);
> +		return;
> +	}
> +
> +	atomic_set(&req_stream_data->frame_done_work.is_queued, 1);
> +	frame_done_work = &req_stream_data->frame_done_work;
> +	queue_work(ctx->frame_done_wq, &frame_done_work->work);
> +}
> +

[snip]

> +static bool mtk_camsys_is_all_cq_done(struct mtk_cam_ctx *ctx,
> +				      unsigned int pipe_id)
> +{
> +	unsigned int all_subdevs = 0;
> +	bool ret = false;
> +
> +	spin_lock(&ctx->first_cq_lock);
> +	if (ctx->is_first_cq_done) {
> +		ret = true;
> +		spin_unlock(&ctx->first_cq_lock);
> +		goto EXIT;
> +	}
> +
> +	// update cq done status

Run checkpatch.pl before you send out patch.
checkpatch would tell you not to use c++ style comment.

> +	ctx->cq_done_status |= (1 << pipe_id);
> +
> +	// check cq done status
> +	if (ctx->used_raw_num)
> +		all_subdevs |= (1 << ctx->pipe->id);
> +	if ((ctx->cq_done_status & all_subdevs) == all_subdevs) {
> +		ctx->is_first_cq_done = 1;
> +		ret = true;
> +	}
> +	spin_unlock(&ctx->first_cq_lock);
> +	dev_info(ctx->cam->dev,
> +		 "[1st-CQD] all done:%d, pipe_id:%d (using raw:%d)\n",
> +		 ctx->is_first_cq_done, pipe_id, ctx->used_raw_num);

Why print is_first_cq_done?
I think this is not necessary.

> +EXIT:
> +	return ret;
> +}
> +
> +static int mtk_camsys_event_handle_raw(struct mtk_cam_device *cam,
> +				       unsigned int engine_id,
> +				       struct mtk_camsys_irq_info *irq_info)
> +{
> +	struct mtk_raw_device *raw_dev;
> +	struct mtk_cam_ctx *ctx;
> +
> +	raw_dev = dev_get_drvdata(cam->raw.devs[engine_id]);
> +	ctx = mtk_cam_find_ctx(cam, &raw_dev->pipeline->subdev.entity);
> +	if (!ctx) {
> +		dev_err(raw_dev->dev, "cannot find ctx\n");
> +		return -EINVAL;
> +	}
> +
> +	/* raw's CQ done */
> +	if (irq_info->irq_type & 1 << CAMSYS_IRQ_SETTING_DONE) {
> +		if (mtk_camsys_is_all_cq_done(ctx, ctx->pipe->id))
> +				mtk_camsys_raw_cq_done(raw_dev, ctx,
> +						       irq_info->frame_idx);
> +	}
> +
> +	/* raw's DMA done, we only allow AFO done here */
> +	if (irq_info->irq_type & 1 << CAMSYS_IRQ_AFO_DONE)
> +		mtk_cam_meta1_done(ctx, ctx->dequeued_frame_seq_no, ctx->stream_id);
> +
> +	/* raw's SW done */
> +	if (irq_info->irq_type & 1 << CAMSYS_IRQ_FRAME_DONE) {
> +		mtk_camsys_frame_done(ctx, ctx->dequeued_frame_seq_no,
> +						ctx->stream_id);
> +	}
> +	/* raw's SOF */
> +	if (irq_info->irq_type & 1 << CAMSYS_IRQ_FRAME_START) {
> +		if (atomic_read(&raw_dev->vf_en) == 0) {
> +			dev_info(raw_dev->dev, "skip sof event when vf off\n");
> +			return 0;
> +		}
> +		mtk_camsys_raw_frame_start(raw_dev, ctx, irq_info);
> +	}
> +
> +	return 0;
> +}
> +

[snip]

> +
> +struct mtk_camsys_irq_normal_data {
> +	/* with normal_status */

mtk_camsys_irq_normal_data is nothing. Drop it.

> +};
> +
> +struct mtk_camsys_irq_error_data {
> +	/* with error_status */
> +	int err_status;
> +};
> +
> +struct mtk_camsys_irq_info {
> +	enum MTK_CAMSYS_IRQ_EVENT irq_type;
> +	u64 ts_ns;
> +	int frame_idx;
> +	int frame_idx_inner;
> +	bool sub_engine;

sub_engine is useless. Drop it.

> +	int write_cnt;
> +	int fbc_cnt;
> +	union {
> +		struct mtk_camsys_irq_normal_data n;
> +		struct mtk_camsys_irq_error_data e;

e is never used. Drop it.

> +	};
> +};
> +
> +enum MTK_CAMSYS_STATE_IDX {
> +	/* For state analysis and controlling for request */
> +	E_STATE_READY = 0x0,
> +	E_STATE_SENINF,

state never change to E_STATE_SENINF. Drop it.

> +	E_STATE_SENSOR,
> +	E_STATE_CQ,
> +	E_STATE_OUTER,
> +	E_STATE_CAMMUX_OUTER_CFG,

state never change to E_STATE_CAMMUX_OUTER_CFG. Drop it.

> +	E_STATE_CAMMUX_OUTER,

state never change to E_STATE_CAMMUX_OUTER. Drop it.

> +	E_STATE_INNER,
> +	E_STATE_DONE_NORMAL,
> +	E_STATE_CQ_SCQ_DELAY,
> +	E_STATE_CAMMUX_OUTER_CFG_DELAY,

state never change to E_STATE_CAMMUX_OUTER_CFG_DELAY. Drop it.

> +	E_STATE_OUTER_HW_DELAY,
> +	E_STATE_INNER_HW_DELAY,
> +	E_STATE_DONE_MISMATCH,
> +};
> +
> +struct mtk_camsys_ctrl_state {
> +	enum MTK_CAMSYS_STATE_IDX estate;
> +	struct list_head state_element;
> +};
> +
> +struct mtk_camsys_link_ctrl {

mtk_camsys_link_ctrl is useless. Drop it.

> +	struct mtk_raw_pipeline *pipe;
> +	struct media_pad remote;
> +	struct mtk_cam_ctx *swapping_ctx;
> +	u8 active;
> +	u8 wait_exchange;
> +};
> +
> +/* per stream from sensor */
> +struct mtk_camsys_sensor_ctrl {
> +	struct mtk_cam_ctx *ctx;
> +	struct kthread_worker *sensorsetting_wq;
> +	struct kthread_work work;
> +	struct hrtimer sensor_deadline_timer;
> +	u64 sof_time;
> +	int timer_req_sensor;
> +	int timer_req_event;
> +	atomic_t sensor_enq_seq_no;
> +	atomic_t sensor_request_seq_no;
> +	atomic_t isp_request_seq_no;
> +	atomic_t isp_enq_seq_no;
> +	atomic_t last_drained_seq_no;
> +	int initial_cq_done;
> +	atomic_t initial_drop_frame_cnt;
> +	struct list_head camsys_state_list;
> +	spinlock_t camsys_state_lock; /* protect camsys_state_list */
> +	/* link change ctrl */
> +	struct mtk_camsys_link_ctrl link_ctrl;

link_ctrl is useless. Drop it.

> +	struct mtk_cam_request *link_change_req;

link_change_req is useless. Drop it.

Regards,
CK

> +};
> +


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ