diff mbox series

[v1,11/14] media: platform: mtk-mdp3: Revise frame change criteria

Message ID 20220117055254.9777-12-roy-cw.yeh@mediatek.com (mailing list archive)
State New, archived
Headers show
Series Add mdp support for mt8195 | expand

Commit Message

roy-cw.yeh Jan. 17, 2022, 5:52 a.m. UTC
From: "Roy-CW.Yeh" <roy-cw.yeh@mediatek.com>

frame_change will trigger MDP SCP to re-calculate path and parameter.
MDP fails when it doesn't get correct parameters to process frame,
and it will activate by the following conditions:

1. first frame
2. Scenario changes (single/dual pipe)
3. input size changes
4. input format changes
5. output size changes (crop included)

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh@mediatek.com>
---
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |  2 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    | 22 +++++++++++++++----
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   | 19 ++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  9 ++++++++
 4 files changed, 48 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index 0fb932ad3560..0eb08ce69781 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -11,6 +11,7 @@ 
 #include <media/v4l2-mem2mem.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
+#include "mtk-mdp3-regs.h"
 #include "mtk-mdp3-comp.h"
 #include "mtk-mdp3-vpu.h"
 
@@ -96,6 +97,7 @@  struct mdp_dev {
 	atomic_t				suspended;
 	atomic_t				job_count;
 	atomic_t				cmdq_count[MDP_CMDQ_NUM];
+	struct mdp_framechange_param		prev_image;
 };
 
 struct mdp_pipe_info {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
index 72a1864d880c..9afe56882208 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
@@ -77,6 +77,7 @@  static void mdp_m2m_worker(struct work_struct *work)
 	struct vb2_v4l2_buffer *src_vb, *dst_vb;
 	struct img_ipi_frameparam param = {0};
 	struct mdp_cmdq_param task = {0};
+	struct mdp_framechange_param cur_frame = {0};
 	enum vb2_buffer_state vb_state = VB2_BUF_STATE_ERROR;
 	int ret;
 
@@ -90,20 +91,33 @@  static void mdp_m2m_worker(struct work_struct *work)
 	param.type = ctx->curr_param.type;
 	param.num_inputs = 1;
 	param.num_outputs = 1;
-	param.frame_change = (ctx->frame_count[MDP_M2M_SRC] == 0);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
 	mdp_set_src_config(&param.inputs[0], frame, &src_vb->vb2_buf);
 	mdp_set_scenario(ctx->mdp_dev, &param, frame);
-	if (param.frame_change)
-		dev_info(&ctx->mdp_dev->pdev->dev,
-			 "MDP Scenario: %d\n", param.type);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	mdp_set_dst_config(&param.outputs[0], frame, &dst_vb->vb2_buf);
 
+	cur_frame.scenario = param.type;
+	cur_frame.frame_count = ctx->frame_count[MDP_M2M_SRC];
+	memcpy(&cur_frame.in, &param.inputs[0], sizeof(cur_frame.in));
+	memcpy(&cur_frame.out, &param.outputs[0], sizeof(cur_frame.out));
+
+	if (mdp_is_framechange(&ctx->mdp_dev->prev_image, &cur_frame)) {
+		memcpy(&ctx->mdp_dev->prev_image, &cur_frame,
+		       sizeof(struct mdp_framechange_param));
+		param.frame_change = true;
+	} else {
+		param.frame_change = false;
+	}
+
+	if (param.frame_change)
+		dev_dbg(&ctx->mdp_dev->pdev->dev,
+			"MDP Scenario: %d\n", param.type);
+
 	param.timestamp = src_vb->vb2_buf.timestamp;
 
 	ret = mdp_vpu_process(&ctx->vpu, &param);
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
index c0a7e3569853..ccd9c338ff49 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
@@ -429,6 +429,25 @@  static u32 mdp_fmt_get_plane_size(const struct mdp_format *fmt,
 	return 0;
 }
 
+bool mdp_is_framechange(struct mdp_framechange_param *prev,
+			struct mdp_framechange_param *cur)
+{
+	if (cur->frame_count == 0 ||
+	    prev->scenario != cur->scenario ||
+	    prev->in.buffer.format.colorformat != cur->in.buffer.format.colorformat ||
+	    prev->in.buffer.format.width != cur->in.buffer.format.width ||
+	    prev->in.buffer.format.height != cur->in.buffer.format.height ||
+	    prev->out.buffer.format.width != cur->out.buffer.format.width ||
+	    prev->out.buffer.format.height != cur->out.buffer.format.height ||
+	    prev->out.crop.left != cur->out.crop.left ||
+	    prev->out.crop.top != cur->out.crop.top ||
+	    prev->out.crop.width != cur->out.crop.width ||
+	    prev->out.crop.height != cur->out.crop.height)
+		return true;
+
+	return false;
+}
+
 void mdp_set_scenario(struct mdp_dev *mdp,
 		      struct img_ipi_frameparam *param,
 		      struct mdp_frame *frame)
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 3547ce10948f..436d5c899bc5 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -397,6 +397,13 @@  struct mdp_frameparam {
 	enum v4l2_quantization		quant;
 };
 
+struct mdp_framechange_param {
+	u8 scenario;
+	u32 frame_count;
+	struct img_input in;
+	struct img_output out;
+};
+
 int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f);
 const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
 					    struct mdp_frameparam *param,
@@ -408,6 +415,8 @@  int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
 int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
 			    const struct v4l2_rect *compose, s32 rotation,
 	const struct mdp_limit *limit);
+bool mdp_is_framechange(struct mdp_framechange_param *prev,
+			struct mdp_framechange_param *cur);
 void mdp_set_scenario(struct mdp_dev *mdp,
 		      struct img_ipi_frameparam *param,
 		      struct mdp_frame *frame);