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 *
__get_plat_cfg(const struct mdp_comp_ctx * ctx)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
get_comp_flag(const struct mdp_comp_ctx * ctx)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
init_rdma(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_rdma_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_rdma_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
wait_rdma_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
init_rsz(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_rsz_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_rsz_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
advance_rsz_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_wrot(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_wrot_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_wrot_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
wait_wrot_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
init_wdma(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_wdma_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_wdma_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
wait_wdma_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
reset_luma_hist(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
init_tdshp(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_tdshp_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_tdshp_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_color(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_color_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_color_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_ccorr(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_ccorr_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_aal(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_aal_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_aal_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_hdr(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_hdr_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_hdr_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_fg(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_fg_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_fg_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_ovl(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_ovl_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)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
config_ovl_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
init_pad(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)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
config_pad_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)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
is_dma_capable(const enum mdp_comp_type type)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
is_bypass_gce_event(const enum mdp_comp_type type)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
mdp_comp_get_id(struct mdp_dev * mdp,enum mdp_comp_type type,u32 alias_id)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
mdp_comp_clock_on(struct device * dev,struct mdp_comp * comp)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
mdp_comp_clock_off(struct device * dev,struct mdp_comp * comp)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
mdp_comp_clocks_on(struct device * dev,struct mdp_comp * comps,int num)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
mdp_comp_clocks_off(struct device * dev,struct mdp_comp * comps,int num)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
mdp_get_subsys_id(struct mdp_dev * mdp,struct device * dev,struct device_node * node,struct mdp_comp * comp)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
__mdp_comp_init(struct mdp_dev * mdp,struct device_node * node,struct mdp_comp * comp)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
mdp_comp_init(struct mdp_dev * mdp,struct device_node * node,struct mdp_comp * comp,enum mtk_mdp_comp_id id)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
mdp_comp_deinit(struct mdp_comp * comp)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
mdp_comp_create(struct mdp_dev * mdp,struct device_node * node,enum mtk_mdp_comp_id id)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
mdp_comp_sub_create(struct mdp_dev * mdp)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
mdp_comp_destroy(struct mdp_dev * mdp)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
mdp_comp_config(struct mdp_dev * mdp)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
mdp_comp_ctx_config(struct mdp_dev * mdp,struct mdp_comp_ctx * ctx,const struct img_compparam * param,const struct img_ipi_frameparam * frame)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