Merge tag 'media/v6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[sfrench/cifs-2.6.git] / drivers / media / platform / mediatek / mdp3 / mtk-mdp3-comp.c
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 }