File Index
Files and directories
Sign in
FILE

mtk-mdp3-comp.c

File preview with syntax highlighting.

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