xref: /linux/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c (revision 72bea132f3680ee51e7ed2cee62892b6f5121909)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022 MediaTek Inc.
4  * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/of_platform.h>
9 #include <linux/of_address.h>
10 #include <linux/pm_runtime.h>
11 #include "mtk-mdp3-cfg.h"
12 #include "mtk-mdp3-comp.h"
13 #include "mtk-mdp3-core.h"
14 #include "mtk-mdp3-regs.h"
15 
16 #include "mdp_reg_aal.h"
17 #include "mdp_reg_ccorr.h"
18 #include "mdp_reg_color.h"
19 #include "mdp_reg_fg.h"
20 #include "mdp_reg_hdr.h"
21 #include "mdp_reg_merge.h"
22 #include "mdp_reg_ovl.h"
23 #include "mdp_reg_pad.h"
24 #include "mdp_reg_rdma.h"
25 #include "mdp_reg_rsz.h"
26 #include "mdp_reg_tdshp.h"
27 #include "mdp_reg_wdma.h"
28 #include "mdp_reg_wrot.h"
29 
30 static u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT];
31 static int p_id;
32 
33 static inline const struct mdp_platform_config *
34 __get_plat_cfg(const struct mdp_comp_ctx *ctx)
35 {
36 	if (!ctx)
37 		return NULL;
38 
39 	return ctx->comp->mdp_dev->mdp_data->mdp_cfg;
40 }
41 
42 static s64 get_comp_flag(const struct mdp_comp_ctx *ctx)
43 {
44 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
45 	u32 rdma0, rsz1;
46 
47 	rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
48 	rsz1 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RSZ1);
49 	if (!rdma0 || !rsz1)
50 		return MDP_COMP_NONE;
51 
52 	if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing)
53 		if (ctx->comp->inner_id == rdma0)
54 			return BIT(rdma0) | BIT(rsz1);
55 
56 	return BIT(ctx->comp->inner_id);
57 }
58 
59 static int init_rdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
60 {
61 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
62 	phys_addr_t base = ctx->comp->reg_base;
63 	u8 subsys_id = ctx->comp->subsys_id;
64 	s32 rdma0;
65 
66 	rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
67 	if (!rdma0)
68 		return -EINVAL;
69 
70 	if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
71 		struct mdp_comp *prz1 = ctx->comp->mdp_dev->comp[MDP_COMP_RSZ1];
72 
73 		/* Disable RSZ1 */
74 		if (ctx->comp->inner_id == rdma0 && prz1)
75 			MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE,
76 				     0x0, BIT(0));
77 	}
78 
79 	/* Reset RDMA */
80 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0));
81 	MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8));
82 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0));
83 	return 0;
84 }
85 
86 static int config_rdma_frame(struct mdp_comp_ctx *ctx,
87 			     struct mdp_cmdq_cmd *cmd,
88 			     const struct v4l2_rect *compose)
89 {
90 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
91 	u32 colorformat = ctx->input->buffer.format.colorformat;
92 	bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
93 	bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
94 	phys_addr_t base = ctx->comp->reg_base;
95 	u8 subsys_id = ctx->comp->subsys_id;
96 	u32 rdma_con_mask = 0;
97 	u32 reg = 0;
98 
99 	if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
100 		if (block10bit)
101 			MM_REG_WRITE(cmd, subsys_id, base,
102 				     MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7);
103 		else
104 			MM_REG_WRITE(cmd, subsys_id, base,
105 				     MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7);
106 	}
107 
108 	/* Setup smi control */
109 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON,
110 		     (7 <<  4) + //burst type to 8
111 		     (1 << 16),  //enable pre-ultra
112 		     0x00030071);
113 
114 	/* Setup source frame info */
115 	if (CFG_CHECK(MT8183, p_id))
116 		reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl);
117 	else if (CFG_CHECK(MT8195, p_id))
118 		reg = CFG_COMP(MT8195, ctx->param, rdma.src_ctrl);
119 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg,
120 		     0x03C8FE0F);
121 
122 	if (mdp_cfg)
123 		if (mdp_cfg->rdma_support_10bit && en_ufo) {
124 			/* Setup source buffer base */
125 			if (CFG_CHECK(MT8183, p_id))
126 				reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y);
127 			else if (CFG_CHECK(MT8195, p_id))
128 				reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_y);
129 			MM_REG_WRITE(cmd, subsys_id,
130 				     base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
131 				     reg, 0xFFFFFFFF);
132 
133 			if (CFG_CHECK(MT8183, p_id))
134 				reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c);
135 			else if (CFG_CHECK(MT8195, p_id))
136 				reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_c);
137 			MM_REG_WRITE(cmd, subsys_id,
138 				     base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
139 				     reg, 0xFFFFFFFF);
140 
141 			/* Set 10bit source frame pitch */
142 			if (block10bit) {
143 				if (CFG_CHECK(MT8183, p_id))
144 					reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl);
145 				else if (CFG_CHECK(MT8195, p_id))
146 					reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd_in_pxl);
147 				MM_REG_WRITE(cmd, subsys_id,
148 					     base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
149 					     reg, 0x001FFFFF);
150 			}
151 		}
152 
153 	if (CFG_CHECK(MT8183, p_id)) {
154 		reg = CFG_COMP(MT8183, ctx->param, rdma.control);
155 		rdma_con_mask = 0x1110;
156 	} else if (CFG_CHECK(MT8195, p_id)) {
157 		reg = CFG_COMP(MT8195, ctx->param, rdma.control);
158 		rdma_con_mask = 0x1130;
159 	}
160 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg,
161 		     rdma_con_mask);
162 
163 	/* Setup source buffer base */
164 	if (CFG_CHECK(MT8183, p_id))
165 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]);
166 	else if (CFG_CHECK(MT8195, p_id))
167 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova[0]);
168 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg,
169 		     0xFFFFFFFF);
170 
171 	if (CFG_CHECK(MT8183, p_id))
172 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]);
173 	else if (CFG_CHECK(MT8195, p_id))
174 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova[1]);
175 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg,
176 		     0xFFFFFFFF);
177 
178 	if (CFG_CHECK(MT8183, p_id))
179 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]);
180 	else if (CFG_CHECK(MT8195, p_id))
181 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova[2]);
182 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg,
183 		     0xFFFFFFFF);
184 
185 	/* Setup source buffer end */
186 	if (CFG_CHECK(MT8183, p_id))
187 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]);
188 	else if (CFG_CHECK(MT8195, p_id))
189 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[0]);
190 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0,
191 		     reg, 0xFFFFFFFF);
192 
193 	if (CFG_CHECK(MT8183, p_id))
194 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]);
195 	else if (CFG_CHECK(MT8195, p_id))
196 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[1]);
197 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1,
198 		     reg, 0xFFFFFFFF);
199 
200 	if (CFG_CHECK(MT8183, p_id))
201 		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]);
202 	else if (CFG_CHECK(MT8195, p_id))
203 		reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[2]);
204 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2,
205 		     reg, 0xFFFFFFFF);
206 
207 	/* Setup source frame pitch */
208 	if (CFG_CHECK(MT8183, p_id))
209 		reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd);
210 	else if (CFG_CHECK(MT8195, p_id))
211 		reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd);
212 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
213 		     reg, 0x001FFFFF);
214 
215 	if (CFG_CHECK(MT8183, p_id))
216 		reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd);
217 	else if (CFG_CHECK(MT8195, p_id))
218 		reg = CFG_COMP(MT8195, ctx->param, rdma.sf_bkgd);
219 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE,
220 		     reg, 0x001FFFFF);
221 
222 	/* Setup color transform */
223 	if (CFG_CHECK(MT8183, p_id))
224 		reg = CFG_COMP(MT8183, ctx->param, rdma.transform);
225 	else if (CFG_CHECK(MT8195, p_id))
226 		reg = CFG_COMP(MT8195, ctx->param, rdma.transform);
227 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
228 		     reg, 0x0F110000);
229 
230 	if (!mdp_cfg || !mdp_cfg->rdma_esl_setting)
231 		goto rdma_config_done;
232 
233 	if (CFG_CHECK(MT8195, p_id))
234 		reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con0);
235 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0,
236 		     reg, 0x0FFF00FF);
237 
238 	if (CFG_CHECK(MT8195, p_id))
239 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con0);
240 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0,
241 		     reg, 0x3FFFFFFF);
242 
243 	if (CFG_CHECK(MT8195, p_id))
244 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con0);
245 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0,
246 		     reg, 0x3FFFFFFF);
247 
248 	if (CFG_CHECK(MT8195, p_id))
249 		reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con1);
250 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1,
251 		     reg, 0x0F7F007F);
252 
253 	if (CFG_CHECK(MT8195, p_id))
254 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con1);
255 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1,
256 		     reg, 0x3FFFFFFF);
257 
258 	if (CFG_CHECK(MT8195, p_id))
259 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con1);
260 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1,
261 		     reg, 0x3FFFFFFF);
262 
263 	if (CFG_CHECK(MT8195, p_id))
264 		reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con2);
265 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2,
266 		     reg, 0x0F3F003F);
267 
268 	if (CFG_CHECK(MT8195, p_id))
269 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con2);
270 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2,
271 		     reg, 0x3FFFFFFF);
272 
273 	if (CFG_CHECK(MT8195, p_id))
274 		reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con2);
275 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2,
276 		     reg, 0x3FFFFFFF);
277 
278 	if (CFG_CHECK(MT8195, p_id))
279 		reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con3);
280 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3,
281 		     reg, 0x0F3F003F);
282 
283 rdma_config_done:
284 	return 0;
285 }
286 
287 static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
288 			      struct mdp_cmdq_cmd *cmd, u32 index)
289 {
290 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
291 	u32 colorformat = ctx->input->buffer.format.colorformat;
292 	bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
293 	bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
294 	phys_addr_t base = ctx->comp->reg_base;
295 	u8 subsys_id = ctx->comp->subsys_id;
296 	u32 csf_l = 0, csf_r = 0;
297 	u32 reg = 0;
298 
299 	/* Enable RDMA */
300 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
301 
302 	/* Set Y pixel offset */
303 	if (CFG_CHECK(MT8183, p_id))
304 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]);
305 	else if (CFG_CHECK(MT8195, p_id))
306 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[0]);
307 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
308 		     reg, 0xFFFFFFFF);
309 
310 	/* Set 10bit UFO mode */
311 	if (mdp_cfg) {
312 		if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo) {
313 			if (CFG_CHECK(MT8183, p_id))
314 				reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p);
315 			else if (CFG_CHECK(MT8195, p_id))
316 				reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset_0_p);
317 			MM_REG_WRITE(cmd, subsys_id, base,
318 				     MDP_RDMA_SRC_OFFSET_0_P,
319 				     reg, 0xFFFFFFFF);
320 		}
321 	}
322 
323 	/* Set U pixel offset */
324 	if (CFG_CHECK(MT8183, p_id))
325 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]);
326 	else if (CFG_CHECK(MT8195, p_id))
327 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[1]);
328 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1,
329 		     reg, 0xFFFFFFFF);
330 
331 	/* Set V pixel offset */
332 	if (CFG_CHECK(MT8183, p_id))
333 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]);
334 	else if (CFG_CHECK(MT8195, p_id))
335 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[2]);
336 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2,
337 		     reg, 0xFFFFFFFF);
338 
339 	/* Set source size */
340 	if (CFG_CHECK(MT8183, p_id))
341 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src);
342 	else if (CFG_CHECK(MT8195, p_id))
343 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].src);
344 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg,
345 		     0x1FFF1FFF);
346 
347 	/* Set target size */
348 	if (CFG_CHECK(MT8183, p_id))
349 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip);
350 	else if (CFG_CHECK(MT8195, p_id))
351 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip);
352 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE,
353 		     reg, 0x1FFF1FFF);
354 
355 	/* Set crop offset */
356 	if (CFG_CHECK(MT8183, p_id))
357 		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst);
358 	else if (CFG_CHECK(MT8195, p_id))
359 		reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip_ofst);
360 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1,
361 		     reg, 0x003F001F);
362 
363 	if (CFG_CHECK(MT8183, p_id)) {
364 		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
365 		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
366 	} else if (CFG_CHECK(MT8195, p_id)) {
367 		csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
368 		csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
369 	}
370 	if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only)
371 		if ((csf_r - csf_l + 1) > 320)
372 			MM_REG_WRITE(cmd, subsys_id, base,
373 				     MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2));
374 
375 	return 0;
376 }
377 
378 static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
379 {
380 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
381 	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
382 	phys_addr_t base = ctx->comp->reg_base;
383 	u8 subsys_id = ctx->comp->subsys_id;
384 
385 	if (!mdp_cfg)
386 		return -EINVAL;
387 
388 	if (ctx->comp->alias_id >= mdp_cfg->rdma_event_num) {
389 		dev_err(dev, "Invalid RDMA event %d\n", ctx->comp->alias_id);
390 		return -EINVAL;
391 	}
392 
393 	MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
394 
395 	/* Disable RDMA */
396 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
397 	return 0;
398 }
399 
400 static const struct mdp_comp_ops rdma_ops = {
401 	.get_comp_flag = get_comp_flag,
402 	.init_comp = init_rdma,
403 	.config_frame = config_rdma_frame,
404 	.config_subfrm = config_rdma_subfrm,
405 	.wait_comp_event = wait_rdma_event,
406 };
407 
408 static int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
409 {
410 	phys_addr_t base = ctx->comp->reg_base;
411 	u8 subsys_id = ctx->comp->subsys_id;
412 
413 	/* Reset RSZ */
414 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16));
415 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16));
416 	/* Enable RSZ */
417 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0));
418 
419 	if (CFG_CHECK(MT8195, p_id)) {
420 		struct device *dev;
421 
422 		dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys;
423 		mtk_mmsys_vpp_rsz_dcm_config(dev, true, NULL);
424 	}
425 
426 	return 0;
427 }
428 
429 static int config_rsz_frame(struct mdp_comp_ctx *ctx,
430 			    struct mdp_cmdq_cmd *cmd,
431 			    const struct v4l2_rect *compose)
432 {
433 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
434 	phys_addr_t base = ctx->comp->reg_base;
435 	u8 subsys_id = ctx->comp->subsys_id;
436 	bool bypass = FALSE;
437 	u32 reg = 0;
438 
439 	if (mdp_cfg && mdp_cfg->rsz_etc_control)
440 		MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0, 0xFFFFFFFF);
441 
442 	if (CFG_CHECK(MT8183, p_id))
443 		bypass = CFG_COMP(MT8183, ctx->param, frame.bypass);
444 	else if (CFG_CHECK(MT8195, p_id))
445 		bypass = CFG_COMP(MT8195, ctx->param, frame.bypass);
446 
447 	if (bypass) {
448 		/* Disable RSZ */
449 		MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0));
450 		return 0;
451 	}
452 
453 	if (CFG_CHECK(MT8183, p_id))
454 		reg = CFG_COMP(MT8183, ctx->param, rsz.control1);
455 	else if (CFG_CHECK(MT8195, p_id))
456 		reg = CFG_COMP(MT8195, ctx->param, rsz.control1);
457 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg,
458 		     0x03FFFDF3);
459 
460 	if (CFG_CHECK(MT8183, p_id))
461 		reg = CFG_COMP(MT8183, ctx->param, rsz.control2);
462 	else if (CFG_CHECK(MT8195, p_id))
463 		reg = CFG_COMP(MT8195, ctx->param, rsz.control2);
464 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
465 		     0x0FFFC290);
466 
467 	if (CFG_CHECK(MT8183, p_id))
468 		reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x);
469 	else if (CFG_CHECK(MT8195, p_id))
470 		reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_x);
471 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP,
472 		     reg, 0x007FFFFF);
473 
474 	if (CFG_CHECK(MT8183, p_id))
475 		reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y);
476 	else if (CFG_CHECK(MT8195, p_id))
477 		reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_y);
478 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP,
479 		     reg, 0x007FFFFF);
480 
481 	return 0;
482 }
483 
484 static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
485 			     struct mdp_cmdq_cmd *cmd, u32 index)
486 {
487 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
488 	phys_addr_t base = ctx->comp->reg_base;
489 	u8 subsys_id = ctx->comp->subsys_id;
490 	u32 csf_l = 0, csf_r = 0;
491 	u32 reg = 0;
492 	u32 id;
493 
494 	if (CFG_CHECK(MT8183, p_id))
495 		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2);
496 	else if (CFG_CHECK(MT8195, p_id))
497 		reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].control2);
498 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
499 		     0x00003800);
500 
501 	if (CFG_CHECK(MT8183, p_id))
502 		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src);
503 	else if (CFG_CHECK(MT8195, p_id))
504 		reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].src);
505 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg,
506 		     0xFFFFFFFF);
507 
508 	if (CFG_CHECK(MT8183, p_id)) {
509 		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
510 		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
511 	} else if (CFG_CHECK(MT8195, p_id)) {
512 		csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
513 		csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
514 	}
515 	if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample)
516 		if ((csf_r - csf_l + 1) <= 16)
517 			MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1,
518 				     BIT(27), BIT(27));
519 
520 	if (CFG_CHECK(MT8183, p_id))
521 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left);
522 	else if (CFG_CHECK(MT8195, p_id))
523 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left);
524 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET,
525 		     reg, 0xFFFF);
526 
527 	if (CFG_CHECK(MT8183, p_id))
528 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix);
529 	else if (CFG_CHECK(MT8195, p_id))
530 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left_subpix);
531 	MM_REG_WRITE(cmd, subsys_id,
532 		     base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET,
533 		     reg, 0x1FFFFF);
534 
535 	if (CFG_CHECK(MT8183, p_id))
536 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top);
537 	else if (CFG_CHECK(MT8195, p_id))
538 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top);
539 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET,
540 		     reg, 0xFFFF);
541 
542 	if (CFG_CHECK(MT8183, p_id))
543 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix);
544 	else if (CFG_CHECK(MT8195, p_id))
545 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top_subpix);
546 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET,
547 		     reg, 0x1FFFFF);
548 
549 	if (CFG_CHECK(MT8183, p_id))
550 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left);
551 	else if (CFG_CHECK(MT8195, p_id))
552 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left);
553 	MM_REG_WRITE(cmd, subsys_id,
554 		     base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET,
555 		     reg, 0xFFFF);
556 
557 	if (CFG_CHECK(MT8183, p_id))
558 		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix);
559 	else if (CFG_CHECK(MT8195, p_id))
560 		reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left_subpix);
561 	MM_REG_WRITE(cmd, subsys_id,
562 		     base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET,
563 		     reg, 0x1FFFFF);
564 
565 	if (CFG_CHECK(MT8183, p_id))
566 		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip);
567 	else if (CFG_CHECK(MT8195, p_id))
568 		reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].clip);
569 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg,
570 		     0xFFFFFFFF);
571 
572 	if (CFG_CHECK(MT8195, p_id)) {
573 		struct device *dev;
574 		struct mdp_comp *merge;
575 		const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data;
576 		enum mtk_mdp_comp_id public_id = ctx->comp->public_id;
577 
578 		switch (public_id) {
579 		case MDP_COMP_RSZ2:
580 			merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE2];
581 			break;
582 		case MDP_COMP_RSZ3:
583 			merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE3];
584 			break;
585 		default:
586 			goto rsz_subfrm_done;
587 		}
588 
589 		if (CFG_CHECK(MT8195, p_id))
590 			reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].rsz_switch);
591 
592 		id = data->comp_data[public_id].match.alias_id;
593 		dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys;
594 		mtk_mmsys_vpp_rsz_merge_config(dev, id, reg, NULL);
595 
596 		if (CFG_CHECK(MT8195, p_id))
597 			reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].merge_cfg);
598 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
599 			     MDP_MERGE_CFG_0, reg, 0xFFFFFFFF);
600 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
601 			     MDP_MERGE_CFG_4, reg, 0xFFFFFFFF);
602 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
603 			     MDP_MERGE_CFG_24, reg, 0xFFFFFFFF);
604 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
605 			     MDP_MERGE_CFG_25, reg, 0xFFFFFFFF);
606 
607 		/* Bypass mode */
608 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
609 			     MDP_MERGE_CFG_12, BIT(0), 0xFFFFFFFF);
610 		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
611 			     MDP_MERGE_ENABLE, BIT(0), 0xFFFFFFFF);
612 	}
613 
614 rsz_subfrm_done:
615 	return 0;
616 }
617 
618 static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx,
619 			      struct mdp_cmdq_cmd *cmd, u32 index)
620 {
621 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
622 
623 	if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) {
624 		phys_addr_t base = ctx->comp->reg_base;
625 		u8 subsys_id = ctx->comp->subsys_id;
626 		u32 csf_l = 0, csf_r = 0;
627 
628 		if (CFG_CHECK(MT8183, p_id)) {
629 			csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
630 			csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
631 		} else if (CFG_CHECK(MT8195, p_id)) {
632 			csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
633 			csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
634 		}
635 
636 		if ((csf_r - csf_l + 1) <= 16)
637 			MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0,
638 				     BIT(27));
639 	}
640 
641 	return 0;
642 }
643 
644 static const struct mdp_comp_ops rsz_ops = {
645 	.get_comp_flag = get_comp_flag,
646 	.init_comp = init_rsz,
647 	.config_frame = config_rsz_frame,
648 	.config_subfrm = config_rsz_subfrm,
649 	.advance_subfrm = advance_rsz_subfrm,
650 };
651 
652 static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
653 {
654 	phys_addr_t base = ctx->comp->reg_base;
655 	u8 subsys_id = ctx->comp->subsys_id;
656 
657 	/* Reset WROT */
658 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0));
659 	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0));
660 
661 	/* Reset setting */
662 	if (CFG_CHECK(MT8195, p_id))
663 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0, 0xFFFFFFFF);
664 
665 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0));
666 	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0));
667 	return 0;
668 }
669 
670 static int config_wrot_frame(struct mdp_comp_ctx *ctx,
671 			     struct mdp_cmdq_cmd *cmd,
672 			     const struct v4l2_rect *compose)
673 {
674 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
675 	phys_addr_t base = ctx->comp->reg_base;
676 	u8 subsys_id = ctx->comp->subsys_id;
677 	u32 reg = 0;
678 
679 	/* Write frame base address */
680 	if (CFG_CHECK(MT8183, p_id))
681 		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]);
682 	else if (CFG_CHECK(MT8195, p_id))
683 		reg = CFG_COMP(MT8195, ctx->param, wrot.iova[0]);
684 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg,
685 		     0xFFFFFFFF);
686 
687 	if (CFG_CHECK(MT8183, p_id))
688 		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]);
689 	else if (CFG_CHECK(MT8195, p_id))
690 		reg = CFG_COMP(MT8195, ctx->param, wrot.iova[1]);
691 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg,
692 		     0xFFFFFFFF);
693 
694 	if (CFG_CHECK(MT8183, p_id))
695 		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]);
696 	else if (CFG_CHECK(MT8195, p_id))
697 		reg = CFG_COMP(MT8195, ctx->param, wrot.iova[2]);
698 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg,
699 		     0xFFFFFFFF);
700 
701 	if (mdp_cfg && mdp_cfg->wrot_support_10bit) {
702 		if (CFG_CHECK(MT8195, p_id))
703 			reg = CFG_COMP(MT8195, ctx->param, wrot.scan_10bit);
704 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT,
705 			     reg, 0x0000000F);
706 
707 		if (CFG_CHECK(MT8195, p_id))
708 			reg = CFG_COMP(MT8195, ctx->param, wrot.pending_zero);
709 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO,
710 			     reg, 0x04000000);
711 	}
712 
713 	if (CFG_CHECK(MT8195, p_id)) {
714 		reg = CFG_COMP(MT8195, ctx->param, wrot.bit_number);
715 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2,
716 			     reg, 0x00000007);
717 	}
718 
719 	/* Write frame related registers */
720 	if (CFG_CHECK(MT8183, p_id))
721 		reg = CFG_COMP(MT8183, ctx->param, wrot.control);
722 	else if (CFG_CHECK(MT8195, p_id))
723 		reg = CFG_COMP(MT8195, ctx->param, wrot.control);
724 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg,
725 		     0xF131510F);
726 
727 	/* Write pre-ultra threshold */
728 	if (CFG_CHECK(MT8195, p_id)) {
729 		reg = CFG_COMP(MT8195, ctx->param, wrot.pre_ultra);
730 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA, reg,
731 			     0x00FFFFFF);
732 	}
733 
734 	/* Write frame Y pitch */
735 	if (CFG_CHECK(MT8183, p_id))
736 		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]);
737 	else if (CFG_CHECK(MT8195, p_id))
738 		reg = CFG_COMP(MT8195, ctx->param, wrot.stride[0]);
739 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg,
740 		     0x0000FFFF);
741 
742 	/* Write frame UV pitch */
743 	if (CFG_CHECK(MT8183, p_id))
744 		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]);
745 	else if (CFG_CHECK(MT8195, p_id))
746 		reg = CFG_COMP(MT8195, ctx->param, wrot.stride[1]);
747 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg,
748 		     0xFFFF);
749 
750 	if (CFG_CHECK(MT8183, p_id))
751 		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]);
752 	else if (CFG_CHECK(MT8195, p_id))
753 		reg = CFG_COMP(MT8195, ctx->param, wrot.stride[2]);
754 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg,
755 		     0xFFFF);
756 
757 	/* Write matrix control */
758 	if (CFG_CHECK(MT8183, p_id))
759 		reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl);
760 	else if (CFG_CHECK(MT8195, p_id))
761 		reg = CFG_COMP(MT8195, ctx->param, wrot.mat_ctrl);
762 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3);
763 
764 	/* Set the fixed ALPHA as 0xFF */
765 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000,
766 		     0xFF000000);
767 
768 	/* Set VIDO_EOL_SEL */
769 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31));
770 
771 	/* Set VIDO_FIFO_TEST */
772 	if (CFG_CHECK(MT8183, p_id))
773 		reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test);
774 	else if (CFG_CHECK(MT8195, p_id))
775 		reg = CFG_COMP(MT8195, ctx->param, wrot.fifo_test);
776 
777 	if (reg != 0)
778 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
779 			     reg, 0xFFF);
780 
781 	/* Filter enable */
782 	if (mdp_cfg && mdp_cfg->wrot_filter_constraint) {
783 		if (CFG_CHECK(MT8183, p_id))
784 			reg = CFG_COMP(MT8183, ctx->param, wrot.filter);
785 		else if (CFG_CHECK(MT8195, p_id))
786 			reg = CFG_COMP(MT8195, ctx->param, wrot.filter);
787 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
788 			     reg, 0x77);
789 
790 		/* Turn off WROT DMA DCM */
791 		if (CFG_CHECK(MT8195, p_id))
792 			MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN,
793 				     (0x1 << 23) + (0x1 << 20), 0x900000);
794 	}
795 
796 	return 0;
797 }
798 
799 static int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
800 			      struct mdp_cmdq_cmd *cmd, u32 index)
801 {
802 	phys_addr_t base = ctx->comp->reg_base;
803 	u8 subsys_id = ctx->comp->subsys_id;
804 	u32 reg = 0;
805 
806 	/* Write Y pixel offset */
807 	if (CFG_CHECK(MT8183, p_id))
808 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]);
809 	else if (CFG_CHECK(MT8195, p_id))
810 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[0]);
811 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
812 		     reg, 0x0FFFFFFF);
813 
814 	/* Write U pixel offset */
815 	if (CFG_CHECK(MT8183, p_id))
816 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]);
817 	else if (CFG_CHECK(MT8195, p_id))
818 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[1]);
819 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
820 		     reg, 0x0FFFFFFF);
821 
822 	/* Write V pixel offset */
823 	if (CFG_CHECK(MT8183, p_id))
824 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]);
825 	else if (CFG_CHECK(MT8195, p_id))
826 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[2]);
827 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
828 		     reg, 0x0FFFFFFF);
829 
830 	/* Write source size */
831 	if (CFG_CHECK(MT8183, p_id))
832 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src);
833 	else if (CFG_CHECK(MT8195, p_id))
834 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].src);
835 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg,
836 		     0x1FFF1FFF);
837 
838 	/* Write target size */
839 	if (CFG_CHECK(MT8183, p_id))
840 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip);
841 	else if (CFG_CHECK(MT8195, p_id))
842 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip);
843 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg,
844 		     0x1FFF1FFF);
845 
846 	if (CFG_CHECK(MT8183, p_id))
847 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst);
848 	else if (CFG_CHECK(MT8195, p_id))
849 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip_ofst);
850 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg,
851 		     0x1FFF1FFF);
852 
853 	if (CFG_CHECK(MT8183, p_id))
854 		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf);
855 	else if (CFG_CHECK(MT8195, p_id))
856 		reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].main_buf);
857 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
858 		     reg, 0x1FFF7F00);
859 
860 	/* Enable WROT */
861 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0));
862 
863 	return 0;
864 }
865 
866 static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
867 {
868 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
869 	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
870 	phys_addr_t base = ctx->comp->reg_base;
871 	u8 subsys_id = ctx->comp->subsys_id;
872 
873 	if (!mdp_cfg)
874 		return -EINVAL;
875 
876 	if (ctx->comp->alias_id >= mdp_cfg->wrot_event_num) {
877 		dev_err(dev, "Invalid WROT event %d!\n", ctx->comp->alias_id);
878 		return -EINVAL;
879 	}
880 
881 	MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
882 
883 	if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
884 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
885 			     0x77);
886 
887 	/* Disable WROT */
888 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0));
889 
890 	return 0;
891 }
892 
893 static const struct mdp_comp_ops wrot_ops = {
894 	.get_comp_flag = get_comp_flag,
895 	.init_comp = init_wrot,
896 	.config_frame = config_wrot_frame,
897 	.config_subfrm = config_wrot_subfrm,
898 	.wait_comp_event = wait_wrot_event,
899 };
900 
901 static int init_wdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
902 {
903 	phys_addr_t base = ctx->comp->reg_base;
904 	u8 subsys_id = ctx->comp->subsys_id;
905 
906 	/* Reset WDMA */
907 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0));
908 	MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0));
909 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0));
910 	return 0;
911 }
912 
913 static int config_wdma_frame(struct mdp_comp_ctx *ctx,
914 			     struct mdp_cmdq_cmd *cmd,
915 			     const struct v4l2_rect *compose)
916 {
917 	phys_addr_t base = ctx->comp->reg_base;
918 	u8 subsys_id = ctx->comp->subsys_id;
919 	u32 reg = 0;
920 
921 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050,
922 		     0xFFFFFFFF);
923 
924 	/* Setup frame information */
925 	if (CFG_CHECK(MT8183, p_id))
926 		reg = CFG_COMP(MT8183, ctx->param, wdma.wdma_cfg);
927 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, reg,
928 		     0x0F01B8F0);
929 	/* Setup frame base address */
930 	if (CFG_CHECK(MT8183, p_id))
931 		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[0]);
932 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg,
933 		     0xFFFFFFFF);
934 	if (CFG_CHECK(MT8183, p_id))
935 		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[1]);
936 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg,
937 		     0xFFFFFFFF);
938 	if (CFG_CHECK(MT8183, p_id))
939 		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[2]);
940 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg,
941 		     0xFFFFFFFF);
942 	/* Setup Y pitch */
943 	if (CFG_CHECK(MT8183, p_id))
944 		reg = CFG_COMP(MT8183, ctx->param, wdma.w_in_byte);
945 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE,
946 		     reg, 0x0000FFFF);
947 	/* Setup UV pitch */
948 	if (CFG_CHECK(MT8183, p_id))
949 		reg = CFG_COMP(MT8183, ctx->param, wdma.uv_stride);
950 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH,
951 		     reg, 0x0000FFFF);
952 	/* Set the fixed ALPHA as 0xFF */
953 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF,
954 		     0x800000FF);
955 
956 	return 0;
957 }
958 
959 static int config_wdma_subfrm(struct mdp_comp_ctx *ctx,
960 			      struct mdp_cmdq_cmd *cmd, u32 index)
961 {
962 	phys_addr_t base = ctx->comp->reg_base;
963 	u8 subsys_id = ctx->comp->subsys_id;
964 	u32 reg = 0;
965 
966 	/* Write Y pixel offset */
967 	if (CFG_CHECK(MT8183, p_id))
968 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[0]);
969 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET,
970 		     reg, 0x0FFFFFFF);
971 	/* Write U pixel offset */
972 	if (CFG_CHECK(MT8183, p_id))
973 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[1]);
974 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET,
975 		     reg, 0x0FFFFFFF);
976 	/* Write V pixel offset */
977 	if (CFG_CHECK(MT8183, p_id))
978 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[2]);
979 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET,
980 		     reg, 0x0FFFFFFF);
981 	/* Write source size */
982 	if (CFG_CHECK(MT8183, p_id))
983 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].src);
984 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, reg,
985 		     0x3FFF3FFF);
986 	/* Write target size */
987 	if (CFG_CHECK(MT8183, p_id))
988 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip);
989 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg,
990 		     0x3FFF3FFF);
991 	/* Write clip offset */
992 	if (CFG_CHECK(MT8183, p_id))
993 		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip_ofst);
994 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, reg,
995 		     0x3FFF3FFF);
996 
997 	/* Enable WDMA */
998 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0));
999 
1000 	return 0;
1001 }
1002 
1003 static int wait_wdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1004 {
1005 	phys_addr_t base = ctx->comp->reg_base;
1006 	u8 subsys_id = ctx->comp->subsys_id;
1007 
1008 	MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
1009 	/* Disable WDMA */
1010 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0));
1011 	return 0;
1012 }
1013 
1014 static const struct mdp_comp_ops wdma_ops = {
1015 	.get_comp_flag = get_comp_flag,
1016 	.init_comp = init_wdma,
1017 	.config_frame = config_wdma_frame,
1018 	.config_subfrm = config_wdma_subfrm,
1019 	.wait_comp_event = wait_wdma_event,
1020 };
1021 
1022 static int reset_luma_hist(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1023 {
1024 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
1025 	phys_addr_t base = ctx->comp->reg_base;
1026 	u16 subsys_id = ctx->comp->subsys_id;
1027 	u32 hist_num, i;
1028 
1029 	if (!mdp_cfg)
1030 		return -EINVAL;
1031 
1032 	hist_num = mdp_cfg->tdshp_hist_num;
1033 
1034 	/* Reset histogram */
1035 	for (i = 0; i <= hist_num; i++)
1036 		MM_REG_WRITE_MASK(cmd, subsys_id, base,
1037 				  (MDP_LUMA_HIST_INIT + (i << 2)),
1038 				  0, 0xFFFFFFFF);
1039 
1040 	if (mdp_cfg->tdshp_constrain)
1041 		MM_REG_WRITE(cmd, subsys_id, base,
1042 			     MDP_DC_TWO_D_W1_RESULT_INIT, 0, 0xFFFFFFFF);
1043 
1044 	if (mdp_cfg->tdshp_contour)
1045 		for (i = 0; i < hist_num; i++)
1046 			MM_REG_WRITE_MASK(cmd, subsys_id, base,
1047 					  (MDP_CONTOUR_HIST_INIT + (i << 2)),
1048 					  0, 0xFFFFFFFF);
1049 
1050 	return 0;
1051 }
1052 
1053 static int init_tdshp(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1054 {
1055 	phys_addr_t base = ctx->comp->reg_base;
1056 	u16 subsys_id = ctx->comp->subsys_id;
1057 
1058 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CTRL, BIT(0), BIT(0));
1059 	/* Enable FIFO */
1060 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, BIT(1), BIT(1));
1061 
1062 	return reset_luma_hist(ctx, cmd);
1063 }
1064 
1065 static int config_tdshp_frame(struct mdp_comp_ctx *ctx,
1066 			      struct mdp_cmdq_cmd *cmd,
1067 			      const struct v4l2_rect *compose)
1068 {
1069 	phys_addr_t base = ctx->comp->reg_base;
1070 	u16 subsys_id = ctx->comp->subsys_id;
1071 	u32 reg = 0;
1072 
1073 	if (CFG_CHECK(MT8195, p_id))
1074 		reg = CFG_COMP(MT8195, ctx->param, tdshp.cfg);
1075 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, reg, BIT(0));
1076 
1077 	return 0;
1078 }
1079 
1080 static int config_tdshp_subfrm(struct mdp_comp_ctx *ctx,
1081 			       struct mdp_cmdq_cmd *cmd, u32 index)
1082 {
1083 	phys_addr_t base = ctx->comp->reg_base;
1084 	u16 subsys_id = ctx->comp->subsys_id;
1085 	u32 reg = 0;
1086 
1087 	if (CFG_CHECK(MT8195, p_id))
1088 		reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].src);
1089 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE,
1090 		     reg, MDP_TDSHP_INPUT_SIZE_MASK);
1091 
1092 	if (CFG_CHECK(MT8195, p_id))
1093 		reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip_ofst);
1094 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET,
1095 		     reg, 0x00FF00FF);
1096 
1097 	if (CFG_CHECK(MT8195, p_id))
1098 		reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip);
1099 	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE,
1100 		     reg, MDP_TDSHP_OUTPUT_SIZE_MASK);
1101 
1102 	if (CFG_CHECK(MT8195, p_id))
1103 		reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_0);
1104 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00, reg, 0xFFFFFFFF);
1105 
1106 	if (CFG_CHECK(MT8195, p_id))
1107 		reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_1);
1108 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01, reg, 0xFFFFFFFF);
1109 
1110 	return 0;
1111 }
1112 
1113 static const struct mdp_comp_ops tdshp_ops = {
1114 	.get_comp_flag = get_comp_flag,
1115 	.init_comp = init_tdshp,
1116 	.config_frame = config_tdshp_frame,
1117 	.config_subfrm = config_tdshp_subfrm,
1118 };
1119 
1120 static int init_color(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1121 {
1122 	phys_addr_t base = ctx->comp->reg_base;
1123 	u16 subsys_id = ctx->comp->subsys_id;
1124 
1125 	MM_REG_WRITE(cmd, subsys_id, base,
1126 		     MDP_COLOR_START, 0x1, BIT(1) | BIT(0));
1127 	MM_REG_WRITE(cmd, subsys_id, base,
1128 		     MDP_COLOR_WIN_X_MAIN, 0xFFFF0000, 0xFFFFFFFF);
1129 	MM_REG_WRITE(cmd, subsys_id, base,
1130 		     MDP_COLOR_WIN_Y_MAIN, 0xFFFF0000, 0xFFFFFFFF);
1131 
1132 	/* Reset color matrix */
1133 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM1_EN, 0x0, BIT(0));
1134 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM2_EN, 0x0, BIT(0));
1135 
1136 	/* Enable interrupt */
1137 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTEN, 0x7, 0x7);
1138 
1139 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_OUT_SEL, 0x333, 0x333);
1140 
1141 	return 0;
1142 }
1143 
1144 static int config_color_frame(struct mdp_comp_ctx *ctx,
1145 			      struct mdp_cmdq_cmd *cmd,
1146 			      const struct v4l2_rect *compose)
1147 {
1148 	phys_addr_t base = ctx->comp->reg_base;
1149 	u16 subsys_id = ctx->comp->subsys_id;
1150 	u32 reg = 0;
1151 
1152 	if (CFG_CHECK(MT8195, p_id))
1153 		reg = CFG_COMP(MT8195, ctx->param, color.start);
1154 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_START,
1155 		     reg, MDP_COLOR_START_MASK);
1156 
1157 	return 0;
1158 }
1159 
1160 static int config_color_subfrm(struct mdp_comp_ctx *ctx,
1161 			       struct mdp_cmdq_cmd *cmd, u32 index)
1162 {
1163 	phys_addr_t base = ctx->comp->reg_base;
1164 	u16 subsys_id = ctx->comp->subsys_id;
1165 	u32 reg = 0;
1166 
1167 	if (CFG_CHECK(MT8195, p_id))
1168 		reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_hsize);
1169 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_WIDTH,
1170 		     reg, 0x00003FFF);
1171 
1172 	if (CFG_CHECK(MT8195, p_id))
1173 		reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_vsize);
1174 	MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_HEIGHT,
1175 		     reg, 0x00003FFF);
1176 
1177 	return 0;
1178 }
1179 
1180 static const struct mdp_comp_ops color_ops = {
1181 	.get_comp_flag = get_comp_flag,
1182 	.init_comp = init_color,
1183 	.config_frame = config_color_frame,
1184 	.config_subfrm = config_color_subfrm,
1185 };
1186 
1187 static int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1188 {
1189 	phys_addr_t base = ctx->comp->reg_base;
1190 	u8 subsys_id = ctx->comp->subsys_id;
1191 
1192 	/* CCORR enable */
1193 	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0));
1194 	/* Relay mode */
1195 	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0));
1196 	return 0;
1197 }
1198 
1199 static int config_ccorr_subfrm(struct mdp_comp_ctx *ctx,
1200 			       struct mdp_cmdq_cmd *cmd, u32 index)
1201 {
1202 	phys_addr_t base = ctx->comp->reg_base;
1203 	u8 subsys_id = ctx->comp->subsys_id;
1204 	u32 csf_l = 0, csf_r = 0;
1205 	u32 csf_t = 0, csf_b = 0;
1206 	u32 hsize, vsize;
1207 
1208 	if (CFG_CHECK(MT8183, p_id)) {
1209 		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
1210 		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
1211 		csf_t = CFG_COMP(MT8183, ctx->param, subfrms[index].in.top);
1212 		csf_b = CFG_COMP(MT8183, ctx->param, subfrms[index].in.bottom);
1213 	}
1214 
1215 	hsize = csf_r - csf_l + 1;
1216 	vsize = csf_b - csf_t + 1;
1217 	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE,
1218 		     (hsize << 16) + (vsize <<  0), 0x1FFF1FFF);
1219 	return 0;
1220 }
1221 
1222 static const struct mdp_comp_ops ccorr_ops = {
1223 	.get_comp_flag = get_comp_flag,
1224 	.init_comp = init_ccorr,
1225 	.config_subfrm = config_ccorr_subfrm,
1226 };
1227 
1228 static int init_aal(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1229 {
1230 	phys_addr_t base = ctx->comp->reg_base;
1231 	u16 subsys_id = ctx->comp->subsys_id;
1232 
1233 	/* Always set MDP_AAL enable to 1 */
1234 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_EN, BIT(0), BIT(0));
1235 
1236 	return 0;
1237 }
1238 
1239 static int config_aal_frame(struct mdp_comp_ctx *ctx,
1240 			    struct mdp_cmdq_cmd *cmd,
1241 			    const struct v4l2_rect *compose)
1242 {
1243 	phys_addr_t base = ctx->comp->reg_base;
1244 	u16 subsys_id = ctx->comp->subsys_id;
1245 	u32 reg = 0;
1246 
1247 	if (CFG_CHECK(MT8195, p_id))
1248 		reg = CFG_COMP(MT8195, ctx->param, aal.cfg_main);
1249 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, reg, BIT(7));
1250 
1251 	if (CFG_CHECK(MT8195, p_id))
1252 		reg = CFG_COMP(MT8195, ctx->param, aal.cfg);
1253 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG, reg, BIT(0));
1254 
1255 	return 0;
1256 }
1257 
1258 static int config_aal_subfrm(struct mdp_comp_ctx *ctx,
1259 			     struct mdp_cmdq_cmd *cmd, u32 index)
1260 {
1261 	phys_addr_t base = ctx->comp->reg_base;
1262 	u16 subsys_id = ctx->comp->subsys_id;
1263 	u32 reg = 0;
1264 
1265 	if (CFG_CHECK(MT8195, p_id))
1266 		reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].src);
1267 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE,
1268 		     reg, MDP_AAL_SIZE_MASK);
1269 
1270 	if (CFG_CHECK(MT8195, p_id))
1271 		reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip_ofst);
1272 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET,
1273 		     reg, 0x00FF00FF);
1274 
1275 	if (CFG_CHECK(MT8195, p_id))
1276 		reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip);
1277 	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE,
1278 		     reg, MDP_AAL_OUTPUT_SIZE_MASK);
1279 
1280 	return 0;
1281 }
1282 
1283 static const struct mdp_comp_ops aal_ops = {
1284 	.get_comp_flag = get_comp_flag,
1285 	.init_comp = init_aal,
1286 	.config_frame = config_aal_frame,
1287 	.config_subfrm = config_aal_subfrm,
1288 };
1289 
1290 static int init_hdr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1291 {
1292 	phys_addr_t base = ctx->comp->reg_base;
1293 	u16 subsys_id = ctx->comp->subsys_id;
1294 
1295 	/* Always set MDP_HDR enable to 1 */
1296 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, BIT(0), BIT(0));
1297 
1298 	return 0;
1299 }
1300 
1301 static int config_hdr_frame(struct mdp_comp_ctx *ctx,
1302 			    struct mdp_cmdq_cmd *cmd,
1303 			    const struct v4l2_rect *compose)
1304 {
1305 	phys_addr_t base = ctx->comp->reg_base;
1306 	u16 subsys_id = ctx->comp->subsys_id;
1307 	u32 reg = 0;
1308 
1309 	if (CFG_CHECK(MT8195, p_id))
1310 		reg = CFG_COMP(MT8195, ctx->param, hdr.top);
1311 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(29) | BIT(28));
1312 
1313 	if (CFG_CHECK(MT8195, p_id))
1314 		reg = CFG_COMP(MT8195, ctx->param, hdr.relay);
1315 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_RELAY, reg, BIT(0));
1316 
1317 	return 0;
1318 }
1319 
1320 static int config_hdr_subfrm(struct mdp_comp_ctx *ctx,
1321 			     struct mdp_cmdq_cmd *cmd, u32 index)
1322 {
1323 	phys_addr_t base = ctx->comp->reg_base;
1324 	u16 subsys_id = ctx->comp->subsys_id;
1325 	u32 reg = 0;
1326 
1327 	if (CFG_CHECK(MT8195, p_id))
1328 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].win_size);
1329 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS,
1330 		     reg, MDP_HDR_TILE_POS_MASK);
1331 
1332 	if (CFG_CHECK(MT8195, p_id))
1333 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].src);
1334 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_0, reg, 0x1FFF1FFF);
1335 
1336 	if (CFG_CHECK(MT8195, p_id))
1337 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst0);
1338 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_1, reg, 0x1FFF1FFF);
1339 
1340 	if (CFG_CHECK(MT8195, p_id))
1341 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst1);
1342 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_2, reg, 0x1FFF1FFF);
1343 
1344 	if (CFG_CHECK(MT8195, p_id))
1345 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_0);
1346 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0, reg, 0x00003FFF);
1347 
1348 	if (CFG_CHECK(MT8195, p_id))
1349 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_1);
1350 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1, reg, 0x00003FFF);
1351 
1352 	if (CFG_CHECK(MT8195, p_id))
1353 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hdr_top);
1354 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(6) | BIT(5));
1355 
1356 	/* Enable histogram */
1357 	if (CFG_CHECK(MT8195, p_id))
1358 		reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_addr);
1359 	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_ADDR, reg, BIT(9));
1360 
1361 	return 0;
1362 }
1363 
1364 static const struct mdp_comp_ops hdr_ops = {
1365 	.get_comp_flag = get_comp_flag,
1366 	.init_comp = init_hdr,
1367 	.config_frame = config_hdr_frame,
1368 	.config_subfrm = config_hdr_subfrm,
1369 };
1370 
1371 static int init_fg(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1372 {
1373 	phys_addr_t base = ctx->comp->reg_base;
1374 	u16 subsys_id = ctx->comp->subsys_id;
1375 
1376 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, BIT(2), BIT(2));
1377 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, 0x0, BIT(2));
1378 
1379 	return 0;
1380 }
1381 
1382 static int config_fg_frame(struct mdp_comp_ctx *ctx,
1383 			   struct mdp_cmdq_cmd *cmd,
1384 			   const struct v4l2_rect *compose)
1385 {
1386 	phys_addr_t base = ctx->comp->reg_base;
1387 	u16 subsys_id = ctx->comp->subsys_id;
1388 	u32 reg = 0;
1389 
1390 	if (CFG_CHECK(MT8195, p_id))
1391 		reg = CFG_COMP(MT8195, ctx->param, fg.ctrl_0);
1392 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, reg, BIT(0));
1393 
1394 	if (CFG_CHECK(MT8195, p_id))
1395 		reg = CFG_COMP(MT8195, ctx->param, fg.ck_en);
1396 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CK_EN, reg, 0x7);
1397 
1398 	return 0;
1399 }
1400 
1401 static int config_fg_subfrm(struct mdp_comp_ctx *ctx,
1402 			    struct mdp_cmdq_cmd *cmd, u32 index)
1403 {
1404 	phys_addr_t base = ctx->comp->reg_base;
1405 	u16 subsys_id = ctx->comp->subsys_id;
1406 	u32 reg = 0;
1407 
1408 	if (CFG_CHECK(MT8195, p_id))
1409 		reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_0);
1410 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, reg, 0xFFFFFFFF);
1411 
1412 	if (CFG_CHECK(MT8195, p_id))
1413 		reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_1);
1414 	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, reg, 0xFFFFFFFF);
1415 
1416 	return 0;
1417 }
1418 
1419 static const struct mdp_comp_ops fg_ops = {
1420 	.get_comp_flag = get_comp_flag,
1421 	.init_comp = init_fg,
1422 	.config_frame = config_fg_frame,
1423 	.config_subfrm = config_fg_subfrm,
1424 };
1425 
1426 static int init_ovl(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1427 {
1428 	phys_addr_t base = ctx->comp->reg_base;
1429 	u16 subsys_id = ctx->comp->subsys_id;
1430 
1431 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_EN,
1432 		     BIT(0), MDP_OVL_EN_MASK);
1433 
1434 	/* Set to relay mode */
1435 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON,
1436 		     BIT(9), MDP_OVL_SRC_CON_MASK);
1437 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_DP_CON,
1438 		     BIT(0), MDP_OVL_DP_CON_MASK);
1439 
1440 	return 0;
1441 }
1442 
1443 static int config_ovl_frame(struct mdp_comp_ctx *ctx,
1444 			    struct mdp_cmdq_cmd *cmd,
1445 			    const struct v4l2_rect *compose)
1446 {
1447 	phys_addr_t base = ctx->comp->reg_base;
1448 	u16 subsys_id = ctx->comp->subsys_id;
1449 	u32 reg = 0;
1450 
1451 	if (CFG_CHECK(MT8195, p_id))
1452 		reg = CFG_COMP(MT8195, ctx->param, ovl.L0_con);
1453 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_CON, reg, BIT(29) | BIT(28));
1454 
1455 	if (CFG_CHECK(MT8195, p_id))
1456 		reg = CFG_COMP(MT8195, ctx->param, ovl.src_con);
1457 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, reg, BIT(0));
1458 
1459 	return 0;
1460 }
1461 
1462 static int config_ovl_subfrm(struct mdp_comp_ctx *ctx,
1463 			     struct mdp_cmdq_cmd *cmd, u32 index)
1464 {
1465 	phys_addr_t base = ctx->comp->reg_base;
1466 	u16 subsys_id = ctx->comp->subsys_id;
1467 	u32 reg = 0;
1468 
1469 	if (CFG_CHECK(MT8195, p_id))
1470 		reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].L0_src_size);
1471 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_SRC_SIZE,
1472 		     reg, MDP_OVL_L0_SRC_SIZE_MASK);
1473 
1474 	/* Setup output size */
1475 	if (CFG_CHECK(MT8195, p_id))
1476 		reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].roi_size);
1477 	MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_ROI_SIZE,
1478 		     reg, MDP_OVL_ROI_SIZE_MASK);
1479 
1480 	return 0;
1481 }
1482 
1483 static const struct mdp_comp_ops ovl_ops = {
1484 	.get_comp_flag = get_comp_flag,
1485 	.init_comp = init_ovl,
1486 	.config_frame = config_ovl_frame,
1487 	.config_subfrm = config_ovl_subfrm,
1488 };
1489 
1490 static int init_pad(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
1491 {
1492 	phys_addr_t base = ctx->comp->reg_base;
1493 	u16 subsys_id = ctx->comp->subsys_id;
1494 
1495 	MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_CON,
1496 		     BIT(1), MDP_PAD_CON_MASK);
1497 	/* Reset */
1498 	MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_W_SIZE,
1499 		     0, MDP_PAD_W_SIZE_MASK);
1500 	MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_H_SIZE,
1501 		     0, MDP_PAD_H_SIZE_MASK);
1502 
1503 	return 0;
1504 }
1505 
1506 static int config_pad_subfrm(struct mdp_comp_ctx *ctx,
1507 			     struct mdp_cmdq_cmd *cmd, u32 index)
1508 {
1509 	phys_addr_t base = ctx->comp->reg_base;
1510 	u16 subsys_id = ctx->comp->subsys_id;
1511 	u32 reg = 0;
1512 
1513 	if (CFG_CHECK(MT8195, p_id))
1514 		reg = CFG_COMP(MT8195, ctx->param, pad.subfrms[index].pic_size);
1515 	MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_PIC_SIZE,
1516 		     reg, MDP_PAD_PIC_SIZE_MASK);
1517 
1518 	return 0;
1519 }
1520 
1521 static const struct mdp_comp_ops pad_ops = {
1522 	.get_comp_flag = get_comp_flag,
1523 	.init_comp = init_pad,
1524 	.config_subfrm = config_pad_subfrm,
1525 };
1526 
1527 static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
1528 	[MDP_COMP_TYPE_RDMA] =		&rdma_ops,
1529 	[MDP_COMP_TYPE_RSZ] =		&rsz_ops,
1530 	[MDP_COMP_TYPE_WROT] =		&wrot_ops,
1531 	[MDP_COMP_TYPE_WDMA] =		&wdma_ops,
1532 	[MDP_COMP_TYPE_TDSHP] =		&tdshp_ops,
1533 	[MDP_COMP_TYPE_COLOR] =		&color_ops,
1534 	[MDP_COMP_TYPE_CCORR] =		&ccorr_ops,
1535 	[MDP_COMP_TYPE_AAL] =		&aal_ops,
1536 	[MDP_COMP_TYPE_HDR] =		&hdr_ops,
1537 	[MDP_COMP_TYPE_FG] =		&fg_ops,
1538 	[MDP_COMP_TYPE_OVL] =		&ovl_ops,
1539 	[MDP_COMP_TYPE_PAD] =		&pad_ops,
1540 };
1541 
1542 static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
1543 	{
1544 		.compatible = "mediatek,mt8183-mdp3-rdma",
1545 		.data = (void *)MDP_COMP_TYPE_RDMA,
1546 	}, {
1547 		.compatible = "mediatek,mt8183-mdp3-ccorr",
1548 		.data = (void *)MDP_COMP_TYPE_CCORR,
1549 	}, {
1550 		.compatible = "mediatek,mt8183-mdp3-rsz",
1551 		.data = (void *)MDP_COMP_TYPE_RSZ,
1552 	}, {
1553 		.compatible = "mediatek,mt8183-mdp3-wrot",
1554 		.data = (void *)MDP_COMP_TYPE_WROT,
1555 	}, {
1556 		.compatible = "mediatek,mt8183-mdp3-wdma",
1557 		.data = (void *)MDP_COMP_TYPE_WDMA,
1558 	}, {
1559 		.compatible = "mediatek,mt8195-mdp3-rdma",
1560 		.data = (void *)MDP_COMP_TYPE_RDMA,
1561 	}, {
1562 		.compatible = "mediatek,mt8195-mdp3-split",
1563 		.data = (void *)MDP_COMP_TYPE_SPLIT,
1564 	}, {
1565 		.compatible = "mediatek,mt8195-mdp3-stitch",
1566 		.data = (void *)MDP_COMP_TYPE_STITCH,
1567 	}, {
1568 		.compatible = "mediatek,mt8195-mdp3-fg",
1569 		.data = (void *)MDP_COMP_TYPE_FG,
1570 	}, {
1571 		.compatible = "mediatek,mt8195-mdp3-hdr",
1572 		.data = (void *)MDP_COMP_TYPE_HDR,
1573 	}, {
1574 		.compatible = "mediatek,mt8195-mdp3-aal",
1575 		.data = (void *)MDP_COMP_TYPE_AAL,
1576 	}, {
1577 		.compatible = "mediatek,mt8195-mdp3-merge",
1578 		.data = (void *)MDP_COMP_TYPE_MERGE,
1579 	}, {
1580 		.compatible = "mediatek,mt8195-mdp3-tdshp",
1581 		.data = (void *)MDP_COMP_TYPE_TDSHP,
1582 	}, {
1583 		.compatible = "mediatek,mt8195-mdp3-color",
1584 		.data = (void *)MDP_COMP_TYPE_COLOR,
1585 	}, {
1586 		.compatible = "mediatek,mt8195-mdp3-ovl",
1587 		.data = (void *)MDP_COMP_TYPE_OVL,
1588 	}, {
1589 		.compatible = "mediatek,mt8195-mdp3-padding",
1590 		.data = (void *)MDP_COMP_TYPE_PAD,
1591 	}, {
1592 		.compatible = "mediatek,mt8195-mdp3-tcc",
1593 		.data = (void *)MDP_COMP_TYPE_TCC,
1594 	},
1595 	{}
1596 };
1597 
1598 static inline bool is_dma_capable(const enum mdp_comp_type type)
1599 {
1600 	return (type == MDP_COMP_TYPE_RDMA ||
1601 		type == MDP_COMP_TYPE_WROT ||
1602 		type == MDP_COMP_TYPE_WDMA);
1603 }
1604 
1605 static inline bool is_bypass_gce_event(const enum mdp_comp_type type)
1606 {
1607 	/*
1608 	 * Subcomponent PATH is only used for the direction of data flow and
1609 	 * dose not need to wait for GCE event.
1610 	 */
1611 	return (type == MDP_COMP_TYPE_PATH);
1612 }
1613 
1614 static int mdp_comp_get_id(struct mdp_dev *mdp, enum mdp_comp_type type, u32 alias_id)
1615 {
1616 	int i;
1617 
1618 	for (i = 0; i < mdp->mdp_data->comp_data_len; i++)
1619 		if (mdp->mdp_data->comp_data[i].match.type == type &&
1620 		    mdp->mdp_data->comp_data[i].match.alias_id == alias_id)
1621 			return i;
1622 	return -ENODEV;
1623 }
1624 
1625 int mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
1626 {
1627 	int i, ret;
1628 
1629 	/* Only DMA capable components need the pm control */
1630 	if (comp->comp_dev && is_dma_capable(comp->type)) {
1631 		ret = pm_runtime_resume_and_get(comp->comp_dev);
1632 		if (ret < 0) {
1633 			dev_err(dev,
1634 				"Failed to get power, err %d. type:%d id:%d\n",
1635 				ret, comp->type, comp->inner_id);
1636 			return ret;
1637 		}
1638 	}
1639 
1640 	for (i = 0; i < comp->clk_num; i++) {
1641 		if (IS_ERR_OR_NULL(comp->clks[i]))
1642 			continue;
1643 		ret = clk_prepare_enable(comp->clks[i]);
1644 		if (ret) {
1645 			dev_err(dev,
1646 				"Failed to enable clk %d. type:%d id:%d\n",
1647 				i, comp->type, comp->inner_id);
1648 			goto err_revert;
1649 		}
1650 	}
1651 
1652 	return 0;
1653 
1654 err_revert:
1655 	while (--i >= 0) {
1656 		if (IS_ERR_OR_NULL(comp->clks[i]))
1657 			continue;
1658 		clk_disable_unprepare(comp->clks[i]);
1659 	}
1660 	if (comp->comp_dev && is_dma_capable(comp->type))
1661 		pm_runtime_put_sync(comp->comp_dev);
1662 
1663 	return ret;
1664 }
1665 
1666 void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
1667 {
1668 	int i;
1669 
1670 	for (i = 0; i < comp->clk_num; i++) {
1671 		if (IS_ERR_OR_NULL(comp->clks[i]))
1672 			continue;
1673 		clk_disable_unprepare(comp->clks[i]);
1674 	}
1675 
1676 	if (comp->comp_dev && is_dma_capable(comp->type))
1677 		pm_runtime_put(comp->comp_dev);
1678 }
1679 
1680 int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
1681 {
1682 	int i, ret;
1683 
1684 	for (i = 0; i < num; i++) {
1685 		struct mdp_dev *m = comps[i].mdp_dev;
1686 		enum mtk_mdp_comp_id id;
1687 		const struct mdp_comp_blend *b;
1688 
1689 		/* Bypass the dummy component*/
1690 		if (!m)
1691 			continue;
1692 
1693 		ret = mdp_comp_clock_on(dev, &comps[i]);
1694 		if (ret)
1695 			return ret;
1696 
1697 		id = comps[i].public_id;
1698 		b = &m->mdp_data->comp_data[id].blend;
1699 
1700 		if (b && b->aid_clk) {
1701 			ret = mdp_comp_clock_on(dev, m->comp[b->b_id]);
1702 			if (ret)
1703 				return ret;
1704 		}
1705 	}
1706 
1707 	return 0;
1708 }
1709 
1710 void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
1711 {
1712 	int i;
1713 
1714 	for (i = 0; i < num; i++) {
1715 		struct mdp_dev *m = comps[i].mdp_dev;
1716 		enum mtk_mdp_comp_id id;
1717 		const struct mdp_comp_blend *b;
1718 
1719 		/* Bypass the dummy component*/
1720 		if (!m)
1721 			continue;
1722 
1723 		mdp_comp_clock_off(dev, &comps[i]);
1724 
1725 		id = comps[i].public_id;
1726 		b = &m->mdp_data->comp_data[id].blend;
1727 
1728 		if (b && b->aid_clk)
1729 			mdp_comp_clock_off(dev, m->comp[b->b_id]);
1730 	}
1731 }
1732 
1733 static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev,
1734 			     struct device_node *node, struct mdp_comp *comp)
1735 {
1736 	struct platform_device *comp_pdev;
1737 	struct cmdq_client_reg  cmdq_reg;
1738 	int ret = 0;
1739 	int index = 0;
1740 
1741 	if (!dev || !node || !comp)
1742 		return -EINVAL;
1743 
1744 	comp_pdev = of_find_device_by_node(node);
1745 
1746 	if (!comp_pdev) {
1747 		dev_err(dev, "get comp_pdev fail! comp public id=%d, inner id=%d, type=%d\n",
1748 			comp->public_id, comp->inner_id, comp->type);
1749 		return -ENODEV;
1750 	}
1751 
1752 	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
1753 	ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
1754 	if (ret != 0) {
1755 		dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
1756 		put_device(&comp_pdev->dev);
1757 		return -EINVAL;
1758 	}
1759 
1760 	comp->subsys_id = cmdq_reg.subsys;
1761 	dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys);
1762 	put_device(&comp_pdev->dev);
1763 
1764 	return 0;
1765 }
1766 
1767 static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
1768 			    struct mdp_comp *comp)
1769 {
1770 	struct resource res;
1771 	phys_addr_t base;
1772 	int index;
1773 
1774 	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
1775 	if (of_address_to_resource(node, index, &res) < 0)
1776 		base = 0L;
1777 	else
1778 		base = res.start;
1779 
1780 	comp->mdp_dev = mdp;
1781 	comp->regs = of_iomap(node, 0);
1782 	comp->reg_base = base;
1783 }
1784 
1785 static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
1786 			 struct mdp_comp *comp, enum mtk_mdp_comp_id id)
1787 {
1788 	struct device *dev = &mdp->pdev->dev;
1789 	struct platform_device *pdev_c;
1790 	int clk_ofst;
1791 	int i;
1792 	s32 event;
1793 
1794 	if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
1795 		dev_err(dev, "Invalid component id %d\n", id);
1796 		return -EINVAL;
1797 	}
1798 
1799 	pdev_c = of_find_device_by_node(node);
1800 	if (!pdev_c) {
1801 		dev_warn(dev, "can't find platform device of node:%s\n",
1802 			 node->name);
1803 		return -ENODEV;
1804 	}
1805 
1806 	comp->comp_dev = &pdev_c->dev;
1807 	comp->public_id = id;
1808 	comp->type = mdp->mdp_data->comp_data[id].match.type;
1809 	comp->inner_id = mdp->mdp_data->comp_data[id].match.inner_id;
1810 	comp->alias_id = mdp->mdp_data->comp_data[id].match.alias_id;
1811 	comp->ops = mdp_comp_ops[comp->type];
1812 	__mdp_comp_init(mdp, node, comp);
1813 
1814 	comp->clk_num = mdp->mdp_data->comp_data[id].info.clk_num;
1815 	comp->clks = devm_kzalloc(dev, sizeof(struct clk *) * comp->clk_num,
1816 				  GFP_KERNEL);
1817 	if (!comp->clks)
1818 		return -ENOMEM;
1819 
1820 	clk_ofst = mdp->mdp_data->comp_data[id].info.clk_ofst;
1821 
1822 	for (i = 0; i < comp->clk_num; i++) {
1823 		comp->clks[i] = of_clk_get(node, i + clk_ofst);
1824 		if (IS_ERR(comp->clks[i]))
1825 			break;
1826 	}
1827 
1828 	mdp_get_subsys_id(mdp, dev, node, comp);
1829 
1830 	/* Set GCE SOF event */
1831 	if (is_bypass_gce_event(comp->type) ||
1832 	    of_property_read_u32_index(node, "mediatek,gce-events",
1833 				       MDP_GCE_EVENT_SOF, &event))
1834 		event = MDP_GCE_NO_EVENT;
1835 
1836 	comp->gce_event[MDP_GCE_EVENT_SOF] = event;
1837 
1838 	/* Set GCE EOF event */
1839 	if (is_dma_capable(comp->type)) {
1840 		if (of_property_read_u32_index(node, "mediatek,gce-events",
1841 					       MDP_GCE_EVENT_EOF, &event)) {
1842 			dev_err(dev, "Component id %d has no EOF\n", id);
1843 			return -EINVAL;
1844 		}
1845 	} else {
1846 		event = MDP_GCE_NO_EVENT;
1847 	}
1848 
1849 	comp->gce_event[MDP_GCE_EVENT_EOF] = event;
1850 
1851 	return 0;
1852 }
1853 
1854 static void mdp_comp_deinit(struct mdp_comp *comp)
1855 {
1856 	if (!comp)
1857 		return;
1858 
1859 	if (comp->comp_dev && comp->clks) {
1860 		devm_kfree(&comp->mdp_dev->pdev->dev, comp->clks);
1861 		comp->clks = NULL;
1862 	}
1863 
1864 	if (comp->regs)
1865 		iounmap(comp->regs);
1866 }
1867 
1868 static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
1869 					struct device_node *node,
1870 					enum mtk_mdp_comp_id id)
1871 {
1872 	struct device *dev = &mdp->pdev->dev;
1873 	struct mdp_comp *comp;
1874 	int ret;
1875 
1876 	if (mdp->comp[id])
1877 		return ERR_PTR(-EEXIST);
1878 
1879 	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
1880 	if (!comp)
1881 		return ERR_PTR(-ENOMEM);
1882 
1883 	ret = mdp_comp_init(mdp, node, comp, id);
1884 	if (ret) {
1885 		devm_kfree(dev, comp);
1886 		return ERR_PTR(ret);
1887 	}
1888 	mdp->comp[id] = comp;
1889 	mdp->comp[id]->mdp_dev = mdp;
1890 
1891 	dev_dbg(dev, "%s type:%d alias:%d public id:%d inner id:%d base:%#x regs:%p\n",
1892 		dev->of_node->name, comp->type, comp->alias_id, id, comp->inner_id,
1893 		(u32)comp->reg_base, comp->regs);
1894 	return comp;
1895 }
1896 
1897 static int mdp_comp_sub_create(struct mdp_dev *mdp)
1898 {
1899 	struct device *dev = &mdp->pdev->dev;
1900 	struct device_node *node, *parent;
1901 	int ret = 0;
1902 
1903 	parent = dev->of_node->parent;
1904 
1905 	for_each_child_of_node(parent, node) {
1906 		const struct of_device_id *of_id;
1907 		enum mdp_comp_type type;
1908 		int id, alias_id;
1909 		struct mdp_comp *comp;
1910 
1911 		of_id = of_match_node(mdp->mdp_data->mdp_sub_comp_dt_ids, node);
1912 		if (!of_id)
1913 			continue;
1914 		if (!of_device_is_available(node)) {
1915 			dev_dbg(dev, "Skipping disabled sub comp. %pOF\n",
1916 				node);
1917 			continue;
1918 		}
1919 
1920 		type = (enum mdp_comp_type)(uintptr_t)of_id->data;
1921 		alias_id = mdp_comp_alias_id[type];
1922 		id = mdp_comp_get_id(mdp, type, alias_id);
1923 		if (id < 0) {
1924 			dev_err(dev,
1925 				"Fail to get sub comp. id: type %d alias %d\n",
1926 				type, alias_id);
1927 			ret = -EINVAL;
1928 			goto err_free_node;
1929 		}
1930 		mdp_comp_alias_id[type]++;
1931 
1932 		comp = mdp_comp_create(mdp, node, id);
1933 		if (IS_ERR(comp)) {
1934 			ret = PTR_ERR(comp);
1935 			goto err_free_node;
1936 		}
1937 	}
1938 	return ret;
1939 
1940 err_free_node:
1941 	of_node_put(node);
1942 	return ret;
1943 }
1944 
1945 void mdp_comp_destroy(struct mdp_dev *mdp)
1946 {
1947 	int i;
1948 
1949 	for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) {
1950 		if (mdp->comp[i]) {
1951 			if (is_dma_capable(mdp->comp[i]->type))
1952 				pm_runtime_disable(mdp->comp[i]->comp_dev);
1953 			mdp_comp_deinit(mdp->comp[i]);
1954 			devm_kfree(mdp->comp[i]->comp_dev, mdp->comp[i]);
1955 			mdp->comp[i] = NULL;
1956 		}
1957 	}
1958 }
1959 
1960 int mdp_comp_config(struct mdp_dev *mdp)
1961 {
1962 	struct device *dev = &mdp->pdev->dev;
1963 	struct device_node *node, *parent;
1964 	int ret;
1965 
1966 	memset(mdp_comp_alias_id, 0, sizeof(mdp_comp_alias_id));
1967 	p_id = mdp->mdp_data->mdp_plat_id;
1968 
1969 	parent = dev->of_node->parent;
1970 	/* Iterate over sibling MDP function blocks */
1971 	for_each_child_of_node(parent, node) {
1972 		const struct of_device_id *of_id;
1973 		enum mdp_comp_type type;
1974 		int id, alias_id;
1975 		struct mdp_comp *comp;
1976 
1977 		of_id = of_match_node(mdp_comp_dt_ids, node);
1978 		if (!of_id)
1979 			continue;
1980 
1981 		if (!of_device_is_available(node)) {
1982 			dev_dbg(dev, "Skipping disabled component %pOF\n",
1983 				node);
1984 			continue;
1985 		}
1986 
1987 		type = (enum mdp_comp_type)(uintptr_t)of_id->data;
1988 		alias_id = mdp_comp_alias_id[type];
1989 		id = mdp_comp_get_id(mdp, type, alias_id);
1990 		if (id < 0) {
1991 			dev_err(dev,
1992 				"Fail to get component id: type %d alias %d\n",
1993 				type, alias_id);
1994 			continue;
1995 		}
1996 		mdp_comp_alias_id[type]++;
1997 
1998 		comp = mdp_comp_create(mdp, node, id);
1999 		if (IS_ERR(comp)) {
2000 			ret = PTR_ERR(comp);
2001 			of_node_put(node);
2002 			goto err_init_comps;
2003 		}
2004 
2005 		/* Only DMA capable components need the pm control */
2006 		if (!is_dma_capable(comp->type))
2007 			continue;
2008 		pm_runtime_enable(comp->comp_dev);
2009 	}
2010 
2011 	ret = mdp_comp_sub_create(mdp);
2012 	if (ret)
2013 		goto err_init_comps;
2014 
2015 	return 0;
2016 
2017 err_init_comps:
2018 	mdp_comp_destroy(mdp);
2019 	return ret;
2020 }
2021 
2022 int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
2023 			const struct img_compparam *param,
2024 			const struct img_ipi_frameparam *frame)
2025 {
2026 	struct device *dev = &mdp->pdev->dev;
2027 	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
2028 	u32 arg;
2029 	int i, idx;
2030 
2031 	if (!param) {
2032 		dev_err(dev, "Invalid component param");
2033 		return -EINVAL;
2034 	}
2035 
2036 	if (CFG_CHECK(MT8183, p_id))
2037 		arg = CFG_COMP(MT8183, param, type);
2038 	else if (CFG_CHECK(MT8195, p_id))
2039 		arg = CFG_COMP(MT8195, param, type);
2040 	else
2041 		return -EINVAL;
2042 	public_id = mdp_cfg_get_id_public(mdp, arg);
2043 	if (public_id < 0) {
2044 		dev_err(dev, "Invalid component id %d", public_id);
2045 		return -EINVAL;
2046 	}
2047 
2048 	ctx->comp = mdp->comp[public_id];
2049 	if (!ctx->comp) {
2050 		dev_err(dev, "Uninit component inner id %d", arg);
2051 		return -EINVAL;
2052 	}
2053 
2054 	ctx->param = param;
2055 	if (CFG_CHECK(MT8183, p_id))
2056 		arg = CFG_COMP(MT8183, param, input);
2057 	else if (CFG_CHECK(MT8195, p_id))
2058 		arg = CFG_COMP(MT8195, param, input);
2059 	else
2060 		return -EINVAL;
2061 	ctx->input = &frame->inputs[arg];
2062 	if (CFG_CHECK(MT8183, p_id))
2063 		idx = CFG_COMP(MT8183, param, num_outputs);
2064 	else if (CFG_CHECK(MT8195, p_id))
2065 		idx = CFG_COMP(MT8195, param, num_outputs);
2066 	else
2067 		return -EINVAL;
2068 	for (i = 0; i < idx; i++) {
2069 		if (CFG_CHECK(MT8183, p_id))
2070 			arg = CFG_COMP(MT8183, param, outputs[i]);
2071 		else if (CFG_CHECK(MT8195, p_id))
2072 			arg = CFG_COMP(MT8195, param, outputs[i]);
2073 		else
2074 			return -EINVAL;
2075 		ctx->outputs[i] = &frame->outputs[arg];
2076 	}
2077 	return 0;
2078 }
2079