162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2022 MediaTek Inc.
462306a36Sopenharmony_ci * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/clk.h>
862306a36Sopenharmony_ci#include <linux/of_platform.h>
962306a36Sopenharmony_ci#include <linux/of_address.h>
1062306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1162306a36Sopenharmony_ci#include "mtk-mdp3-cfg.h"
1262306a36Sopenharmony_ci#include "mtk-mdp3-comp.h"
1362306a36Sopenharmony_ci#include "mtk-mdp3-core.h"
1462306a36Sopenharmony_ci#include "mtk-mdp3-regs.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "mdp_reg_rdma.h"
1762306a36Sopenharmony_ci#include "mdp_reg_ccorr.h"
1862306a36Sopenharmony_ci#include "mdp_reg_rsz.h"
1962306a36Sopenharmony_ci#include "mdp_reg_wrot.h"
2062306a36Sopenharmony_ci#include "mdp_reg_wdma.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT];
2362306a36Sopenharmony_cistatic int p_id;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic inline const struct mdp_platform_config *
2662306a36Sopenharmony_ci__get_plat_cfg(const struct mdp_comp_ctx *ctx)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	if (!ctx)
2962306a36Sopenharmony_ci		return NULL;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	return ctx->comp->mdp_dev->mdp_data->mdp_cfg;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic s64 get_comp_flag(const struct mdp_comp_ctx *ctx)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
3762306a36Sopenharmony_ci	u32 rdma0, rsz1;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
4062306a36Sopenharmony_ci	rsz1 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RSZ1);
4162306a36Sopenharmony_ci	if (!rdma0 || !rsz1)
4262306a36Sopenharmony_ci		return MDP_COMP_NONE;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing)
4562306a36Sopenharmony_ci		if (ctx->comp->inner_id == rdma0)
4662306a36Sopenharmony_ci			return BIT(rdma0) | BIT(rsz1);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	return BIT(ctx->comp->inner_id);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic int init_rdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
5462306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
5562306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
5662306a36Sopenharmony_ci	s32 rdma0;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
5962306a36Sopenharmony_ci	if (!rdma0)
6062306a36Sopenharmony_ci		return -EINVAL;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
6362306a36Sopenharmony_ci		struct mdp_comp *prz1 = ctx->comp->mdp_dev->comp[MDP_COMP_RSZ1];
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci		/* Disable RSZ1 */
6662306a36Sopenharmony_ci		if (ctx->comp->inner_id == rdma0 && prz1)
6762306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE,
6862306a36Sopenharmony_ci				     0x0, BIT(0));
6962306a36Sopenharmony_ci	}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	/* Reset RDMA */
7262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0));
7362306a36Sopenharmony_ci	MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8));
7462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0));
7562306a36Sopenharmony_ci	return 0;
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic int config_rdma_frame(struct mdp_comp_ctx *ctx,
7962306a36Sopenharmony_ci			     struct mdp_cmdq_cmd *cmd,
8062306a36Sopenharmony_ci			     const struct v4l2_rect *compose)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
8362306a36Sopenharmony_ci	u32 colorformat = ctx->input->buffer.format.colorformat;
8462306a36Sopenharmony_ci	bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
8562306a36Sopenharmony_ci	bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
8662306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
8762306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
8862306a36Sopenharmony_ci	u32 reg = 0;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
9162306a36Sopenharmony_ci		if (block10bit)
9262306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base,
9362306a36Sopenharmony_ci				     MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7);
9462306a36Sopenharmony_ci		else
9562306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base,
9662306a36Sopenharmony_ci				     MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7);
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	/* Setup smi control */
10062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON,
10162306a36Sopenharmony_ci		     (7 <<  4) + //burst type to 8
10262306a36Sopenharmony_ci		     (1 << 16),  //enable pre-ultra
10362306a36Sopenharmony_ci		     0x00030071);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	/* Setup source frame info */
10662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
10762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl);
10862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg,
10962306a36Sopenharmony_ci		     0x03C8FE0F);
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	if (mdp_cfg)
11262306a36Sopenharmony_ci		if (mdp_cfg->rdma_support_10bit && en_ufo) {
11362306a36Sopenharmony_ci			/* Setup source buffer base */
11462306a36Sopenharmony_ci			if (CFG_CHECK(MT8183, p_id))
11562306a36Sopenharmony_ci				reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y);
11662306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id,
11762306a36Sopenharmony_ci				     base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
11862306a36Sopenharmony_ci				     reg, 0xFFFFFFFF);
11962306a36Sopenharmony_ci			if (CFG_CHECK(MT8183, p_id))
12062306a36Sopenharmony_ci				reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c);
12162306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id,
12262306a36Sopenharmony_ci				     base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
12362306a36Sopenharmony_ci				     reg, 0xFFFFFFFF);
12462306a36Sopenharmony_ci			/* Set 10bit source frame pitch */
12562306a36Sopenharmony_ci			if (block10bit) {
12662306a36Sopenharmony_ci				if (CFG_CHECK(MT8183, p_id))
12762306a36Sopenharmony_ci					reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl);
12862306a36Sopenharmony_ci				MM_REG_WRITE(cmd, subsys_id,
12962306a36Sopenharmony_ci					     base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
13062306a36Sopenharmony_ci					     reg, 0x001FFFFF);
13162306a36Sopenharmony_ci			}
13262306a36Sopenharmony_ci		}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
13562306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.control);
13662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg,
13762306a36Sopenharmony_ci		     0x1110);
13862306a36Sopenharmony_ci	/* Setup source buffer base */
13962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
14062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]);
14162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg,
14262306a36Sopenharmony_ci		     0xFFFFFFFF);
14362306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
14462306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]);
14562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg,
14662306a36Sopenharmony_ci		     0xFFFFFFFF);
14762306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
14862306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]);
14962306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg,
15062306a36Sopenharmony_ci		     0xFFFFFFFF);
15162306a36Sopenharmony_ci	/* Setup source buffer end */
15262306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
15362306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]);
15462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0,
15562306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
15662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
15762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]);
15862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1,
15962306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
16062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
16162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]);
16262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2,
16362306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
16462306a36Sopenharmony_ci	/* Setup source frame pitch */
16562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
16662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd);
16762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
16862306a36Sopenharmony_ci		     reg, 0x001FFFFF);
16962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
17062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd);
17162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE,
17262306a36Sopenharmony_ci		     reg, 0x001FFFFF);
17362306a36Sopenharmony_ci	/* Setup color transform */
17462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
17562306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.transform);
17662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
17762306a36Sopenharmony_ci		     reg, 0x0F110000);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	return 0;
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistatic int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
18362306a36Sopenharmony_ci			      struct mdp_cmdq_cmd *cmd, u32 index)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
18662306a36Sopenharmony_ci	u32 colorformat = ctx->input->buffer.format.colorformat;
18762306a36Sopenharmony_ci	bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
18862306a36Sopenharmony_ci	bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
18962306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
19062306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
19162306a36Sopenharmony_ci	u32 csf_l = 0, csf_r = 0;
19262306a36Sopenharmony_ci	u32 reg = 0;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	/* Enable RDMA */
19562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	/* Set Y pixel offset */
19862306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
19962306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]);
20062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
20162306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	/* Set 10bit UFO mode */
20462306a36Sopenharmony_ci	if (mdp_cfg) {
20562306a36Sopenharmony_ci		if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo) {
20662306a36Sopenharmony_ci			if (CFG_CHECK(MT8183, p_id))
20762306a36Sopenharmony_ci				reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p);
20862306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base,
20962306a36Sopenharmony_ci				     MDP_RDMA_SRC_OFFSET_0_P,
21062306a36Sopenharmony_ci				     reg, 0xFFFFFFFF);
21162306a36Sopenharmony_ci		}
21262306a36Sopenharmony_ci	}
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	/* Set U pixel offset */
21562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
21662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]);
21762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1,
21862306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
21962306a36Sopenharmony_ci	/* Set V pixel offset */
22062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
22162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]);
22262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2,
22362306a36Sopenharmony_ci		     reg, 0xFFFFFFFF);
22462306a36Sopenharmony_ci	/* Set source size */
22562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
22662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src);
22762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg,
22862306a36Sopenharmony_ci		     0x1FFF1FFF);
22962306a36Sopenharmony_ci	/* Set target size */
23062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
23162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip);
23262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE,
23362306a36Sopenharmony_ci		     reg, 0x1FFF1FFF);
23462306a36Sopenharmony_ci	/* Set crop offset */
23562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
23662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst);
23762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1,
23862306a36Sopenharmony_ci		     reg, 0x003F001F);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id)) {
24162306a36Sopenharmony_ci		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
24262306a36Sopenharmony_ci		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
24362306a36Sopenharmony_ci	}
24462306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only)
24562306a36Sopenharmony_ci		if ((csf_r - csf_l + 1) > 320)
24662306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base,
24762306a36Sopenharmony_ci				     MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2));
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	return 0;
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_cistatic int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
25362306a36Sopenharmony_ci{
25462306a36Sopenharmony_ci	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
25562306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
25662306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	if (ctx->comp->alias_id == 0)
25962306a36Sopenharmony_ci		MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
26062306a36Sopenharmony_ci	else
26162306a36Sopenharmony_ci		dev_err(dev, "Do not support RDMA1_DONE event\n");
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	/* Disable RDMA */
26462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
26562306a36Sopenharmony_ci	return 0;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic const struct mdp_comp_ops rdma_ops = {
26962306a36Sopenharmony_ci	.get_comp_flag = get_comp_flag,
27062306a36Sopenharmony_ci	.init_comp = init_rdma,
27162306a36Sopenharmony_ci	.config_frame = config_rdma_frame,
27262306a36Sopenharmony_ci	.config_subfrm = config_rdma_subfrm,
27362306a36Sopenharmony_ci	.wait_comp_event = wait_rdma_event,
27462306a36Sopenharmony_ci};
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
27962306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	/* Reset RSZ */
28262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16));
28362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16));
28462306a36Sopenharmony_ci	/* Enable RSZ */
28562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0));
28662306a36Sopenharmony_ci	return 0;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistatic int config_rsz_frame(struct mdp_comp_ctx *ctx,
29062306a36Sopenharmony_ci			    struct mdp_cmdq_cmd *cmd,
29162306a36Sopenharmony_ci			    const struct v4l2_rect *compose)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
29462306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
29562306a36Sopenharmony_ci	bool bypass = FALSE;
29662306a36Sopenharmony_ci	u32 reg = 0;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
29962306a36Sopenharmony_ci		bypass = CFG_COMP(MT8183, ctx->param, frame.bypass);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	if (bypass) {
30262306a36Sopenharmony_ci		/* Disable RSZ */
30362306a36Sopenharmony_ci		MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0));
30462306a36Sopenharmony_ci		return 0;
30562306a36Sopenharmony_ci	}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
30862306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.control1);
30962306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg,
31062306a36Sopenharmony_ci		     0x03FFFDF3);
31162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
31262306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.control2);
31362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
31462306a36Sopenharmony_ci		     0x0FFFC290);
31562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
31662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x);
31762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP,
31862306a36Sopenharmony_ci		     reg, 0x007FFFFF);
31962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
32062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y);
32162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP,
32262306a36Sopenharmony_ci		     reg, 0x007FFFFF);
32362306a36Sopenharmony_ci	return 0;
32462306a36Sopenharmony_ci}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
32762306a36Sopenharmony_ci			     struct mdp_cmdq_cmd *cmd, u32 index)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
33062306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
33162306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
33262306a36Sopenharmony_ci	u32 csf_l = 0, csf_r = 0;
33362306a36Sopenharmony_ci	u32 reg = 0;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
33662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2);
33762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
33862306a36Sopenharmony_ci		     0x00003800);
33962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
34062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src);
34162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg,
34262306a36Sopenharmony_ci		     0xFFFFFFFF);
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id)) {
34562306a36Sopenharmony_ci		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
34662306a36Sopenharmony_ci		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample)
34962306a36Sopenharmony_ci		if ((csf_r - csf_l + 1) <= 16)
35062306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1,
35162306a36Sopenharmony_ci				     BIT(27), BIT(27));
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
35462306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left);
35562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET,
35662306a36Sopenharmony_ci		     reg, 0xFFFF);
35762306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
35862306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix);
35962306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id,
36062306a36Sopenharmony_ci		     base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET,
36162306a36Sopenharmony_ci		     reg, 0x1FFFFF);
36262306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
36362306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top);
36462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET,
36562306a36Sopenharmony_ci		     reg, 0xFFFF);
36662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
36762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix);
36862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET,
36962306a36Sopenharmony_ci		     reg, 0x1FFFFF);
37062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
37162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left);
37262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id,
37362306a36Sopenharmony_ci		     base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET,
37462306a36Sopenharmony_ci		     reg, 0xFFFF);
37562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
37662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix);
37762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id,
37862306a36Sopenharmony_ci		     base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET,
37962306a36Sopenharmony_ci		     reg, 0x1FFFFF);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
38262306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip);
38362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg,
38462306a36Sopenharmony_ci		     0xFFFFFFFF);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	return 0;
38762306a36Sopenharmony_ci}
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic int advance_rsz_subfrm(struct mdp_comp_ctx *ctx,
39062306a36Sopenharmony_ci			      struct mdp_cmdq_cmd *cmd, u32 index)
39162306a36Sopenharmony_ci{
39262306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) {
39562306a36Sopenharmony_ci		phys_addr_t base = ctx->comp->reg_base;
39662306a36Sopenharmony_ci		u8 subsys_id = ctx->comp->subsys_id;
39762306a36Sopenharmony_ci		u32 csf_l = 0, csf_r = 0;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		if (CFG_CHECK(MT8183, p_id)) {
40062306a36Sopenharmony_ci			csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
40162306a36Sopenharmony_ci			csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
40262306a36Sopenharmony_ci		}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci		if ((csf_r - csf_l + 1) <= 16)
40562306a36Sopenharmony_ci			MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0,
40662306a36Sopenharmony_ci				     BIT(27));
40762306a36Sopenharmony_ci	}
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	return 0;
41062306a36Sopenharmony_ci}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_cistatic const struct mdp_comp_ops rsz_ops = {
41362306a36Sopenharmony_ci	.get_comp_flag = get_comp_flag,
41462306a36Sopenharmony_ci	.init_comp = init_rsz,
41562306a36Sopenharmony_ci	.config_frame = config_rsz_frame,
41662306a36Sopenharmony_ci	.config_subfrm = config_rsz_subfrm,
41762306a36Sopenharmony_ci	.advance_subfrm = advance_rsz_subfrm,
41862306a36Sopenharmony_ci};
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
42162306a36Sopenharmony_ci{
42262306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
42362306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	/* Reset WROT */
42662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0));
42762306a36Sopenharmony_ci	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0));
42862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0));
42962306a36Sopenharmony_ci	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0));
43062306a36Sopenharmony_ci	return 0;
43162306a36Sopenharmony_ci}
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_cistatic int config_wrot_frame(struct mdp_comp_ctx *ctx,
43462306a36Sopenharmony_ci			     struct mdp_cmdq_cmd *cmd,
43562306a36Sopenharmony_ci			     const struct v4l2_rect *compose)
43662306a36Sopenharmony_ci{
43762306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
43862306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
43962306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
44062306a36Sopenharmony_ci	u32 reg = 0;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	/* Write frame base address */
44362306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
44462306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]);
44562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg,
44662306a36Sopenharmony_ci		     0xFFFFFFFF);
44762306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
44862306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]);
44962306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg,
45062306a36Sopenharmony_ci		     0xFFFFFFFF);
45162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
45262306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]);
45362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg,
45462306a36Sopenharmony_ci		     0xFFFFFFFF);
45562306a36Sopenharmony_ci	/* Write frame related registers */
45662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
45762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.control);
45862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg,
45962306a36Sopenharmony_ci		     0xF131510F);
46062306a36Sopenharmony_ci	/* Write frame Y pitch */
46162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
46262306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]);
46362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg,
46462306a36Sopenharmony_ci		     0x0000FFFF);
46562306a36Sopenharmony_ci	/* Write frame UV pitch */
46662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
46762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]);
46862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg,
46962306a36Sopenharmony_ci		     0xFFFF);
47062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
47162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]);
47262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg,
47362306a36Sopenharmony_ci		     0xFFFF);
47462306a36Sopenharmony_ci	/* Write matrix control */
47562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
47662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl);
47762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	/* Set the fixed ALPHA as 0xFF */
48062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000,
48162306a36Sopenharmony_ci		     0xFF000000);
48262306a36Sopenharmony_ci	/* Set VIDO_EOL_SEL */
48362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31));
48462306a36Sopenharmony_ci	/* Set VIDO_FIFO_TEST */
48562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
48662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test);
48762306a36Sopenharmony_ci	if (reg != 0)
48862306a36Sopenharmony_ci		MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
48962306a36Sopenharmony_ci			     reg, 0xFFF);
49062306a36Sopenharmony_ci	/* Filter enable */
49162306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->wrot_filter_constraint) {
49262306a36Sopenharmony_ci		if (CFG_CHECK(MT8183, p_id))
49362306a36Sopenharmony_ci			reg = CFG_COMP(MT8183, ctx->param, wrot.filter);
49462306a36Sopenharmony_ci		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
49562306a36Sopenharmony_ci			     reg, 0x77);
49662306a36Sopenharmony_ci	}
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	return 0;
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_cistatic int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
50262306a36Sopenharmony_ci			      struct mdp_cmdq_cmd *cmd, u32 index)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
50562306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
50662306a36Sopenharmony_ci	u32 reg = 0;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	/* Write Y pixel offset */
50962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
51062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]);
51162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
51262306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
51362306a36Sopenharmony_ci	/* Write U pixel offset */
51462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
51562306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]);
51662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
51762306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
51862306a36Sopenharmony_ci	/* Write V pixel offset */
51962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
52062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]);
52162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
52262306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
52362306a36Sopenharmony_ci	/* Write source size */
52462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
52562306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src);
52662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg,
52762306a36Sopenharmony_ci		     0x1FFF1FFF);
52862306a36Sopenharmony_ci	/* Write target size */
52962306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
53062306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip);
53162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg,
53262306a36Sopenharmony_ci		     0x1FFF1FFF);
53362306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
53462306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst);
53562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg,
53662306a36Sopenharmony_ci		     0x1FFF1FFF);
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
53962306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf);
54062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
54162306a36Sopenharmony_ci		     reg, 0x1FFF7F00);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	/* Enable WROT */
54462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0));
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	return 0;
54762306a36Sopenharmony_ci}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cistatic int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
55062306a36Sopenharmony_ci{
55162306a36Sopenharmony_ci	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
55262306a36Sopenharmony_ci	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
55362306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
55462306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	if (ctx->comp->alias_id == 0)
55762306a36Sopenharmony_ci		MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
55862306a36Sopenharmony_ci	else
55962306a36Sopenharmony_ci		dev_err(dev, "Do not support WROT1_DONE event\n");
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
56262306a36Sopenharmony_ci		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
56362306a36Sopenharmony_ci			     0x77);
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	/* Disable WROT */
56662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0));
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	return 0;
56962306a36Sopenharmony_ci}
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_cistatic const struct mdp_comp_ops wrot_ops = {
57262306a36Sopenharmony_ci	.get_comp_flag = get_comp_flag,
57362306a36Sopenharmony_ci	.init_comp = init_wrot,
57462306a36Sopenharmony_ci	.config_frame = config_wrot_frame,
57562306a36Sopenharmony_ci	.config_subfrm = config_wrot_subfrm,
57662306a36Sopenharmony_ci	.wait_comp_event = wait_wrot_event,
57762306a36Sopenharmony_ci};
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_cistatic int init_wdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
58062306a36Sopenharmony_ci{
58162306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
58262306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	/* Reset WDMA */
58562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0));
58662306a36Sopenharmony_ci	MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0));
58762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0));
58862306a36Sopenharmony_ci	return 0;
58962306a36Sopenharmony_ci}
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_cistatic int config_wdma_frame(struct mdp_comp_ctx *ctx,
59262306a36Sopenharmony_ci			     struct mdp_cmdq_cmd *cmd,
59362306a36Sopenharmony_ci			     const struct v4l2_rect *compose)
59462306a36Sopenharmony_ci{
59562306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
59662306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
59762306a36Sopenharmony_ci	u32 reg = 0;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050,
60062306a36Sopenharmony_ci		     0xFFFFFFFF);
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	/* Setup frame information */
60362306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
60462306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.wdma_cfg);
60562306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, reg,
60662306a36Sopenharmony_ci		     0x0F01B8F0);
60762306a36Sopenharmony_ci	/* Setup frame base address */
60862306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
60962306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[0]);
61062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg,
61162306a36Sopenharmony_ci		     0xFFFFFFFF);
61262306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
61362306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[1]);
61462306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg,
61562306a36Sopenharmony_ci		     0xFFFFFFFF);
61662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
61762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.iova[2]);
61862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg,
61962306a36Sopenharmony_ci		     0xFFFFFFFF);
62062306a36Sopenharmony_ci	/* Setup Y pitch */
62162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
62262306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.w_in_byte);
62362306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE,
62462306a36Sopenharmony_ci		     reg, 0x0000FFFF);
62562306a36Sopenharmony_ci	/* Setup UV pitch */
62662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
62762306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.uv_stride);
62862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH,
62962306a36Sopenharmony_ci		     reg, 0x0000FFFF);
63062306a36Sopenharmony_ci	/* Set the fixed ALPHA as 0xFF */
63162306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF,
63262306a36Sopenharmony_ci		     0x800000FF);
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	return 0;
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic int config_wdma_subfrm(struct mdp_comp_ctx *ctx,
63862306a36Sopenharmony_ci			      struct mdp_cmdq_cmd *cmd, u32 index)
63962306a36Sopenharmony_ci{
64062306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
64162306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
64262306a36Sopenharmony_ci	u32 reg = 0;
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	/* Write Y pixel offset */
64562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
64662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[0]);
64762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET,
64862306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
64962306a36Sopenharmony_ci	/* Write U pixel offset */
65062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
65162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[1]);
65262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET,
65362306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
65462306a36Sopenharmony_ci	/* Write V pixel offset */
65562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
65662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[2]);
65762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET,
65862306a36Sopenharmony_ci		     reg, 0x0FFFFFFF);
65962306a36Sopenharmony_ci	/* Write source size */
66062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
66162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].src);
66262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, reg,
66362306a36Sopenharmony_ci		     0x3FFF3FFF);
66462306a36Sopenharmony_ci	/* Write target size */
66562306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
66662306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip);
66762306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg,
66862306a36Sopenharmony_ci		     0x3FFF3FFF);
66962306a36Sopenharmony_ci	/* Write clip offset */
67062306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
67162306a36Sopenharmony_ci		reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip_ofst);
67262306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, reg,
67362306a36Sopenharmony_ci		     0x3FFF3FFF);
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	/* Enable WDMA */
67662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0));
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	return 0;
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic int wait_wdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
68262306a36Sopenharmony_ci{
68362306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
68462306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
68762306a36Sopenharmony_ci	/* Disable WDMA */
68862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0));
68962306a36Sopenharmony_ci	return 0;
69062306a36Sopenharmony_ci}
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_cistatic const struct mdp_comp_ops wdma_ops = {
69362306a36Sopenharmony_ci	.get_comp_flag = get_comp_flag,
69462306a36Sopenharmony_ci	.init_comp = init_wdma,
69562306a36Sopenharmony_ci	.config_frame = config_wdma_frame,
69662306a36Sopenharmony_ci	.config_subfrm = config_wdma_subfrm,
69762306a36Sopenharmony_ci	.wait_comp_event = wait_wdma_event,
69862306a36Sopenharmony_ci};
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_cistatic int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
70162306a36Sopenharmony_ci{
70262306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
70362306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	/* CCORR enable */
70662306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0));
70762306a36Sopenharmony_ci	/* Relay mode */
70862306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0));
70962306a36Sopenharmony_ci	return 0;
71062306a36Sopenharmony_ci}
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_cistatic int config_ccorr_subfrm(struct mdp_comp_ctx *ctx,
71362306a36Sopenharmony_ci			       struct mdp_cmdq_cmd *cmd, u32 index)
71462306a36Sopenharmony_ci{
71562306a36Sopenharmony_ci	phys_addr_t base = ctx->comp->reg_base;
71662306a36Sopenharmony_ci	u8 subsys_id = ctx->comp->subsys_id;
71762306a36Sopenharmony_ci	u32 csf_l = 0, csf_r = 0;
71862306a36Sopenharmony_ci	u32 csf_t = 0, csf_b = 0;
71962306a36Sopenharmony_ci	u32 hsize, vsize;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id)) {
72262306a36Sopenharmony_ci		csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
72362306a36Sopenharmony_ci		csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
72462306a36Sopenharmony_ci		csf_t = CFG_COMP(MT8183, ctx->param, subfrms[index].in.top);
72562306a36Sopenharmony_ci		csf_b = CFG_COMP(MT8183, ctx->param, subfrms[index].in.bottom);
72662306a36Sopenharmony_ci	}
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	hsize = csf_r - csf_l + 1;
72962306a36Sopenharmony_ci	vsize = csf_b - csf_t + 1;
73062306a36Sopenharmony_ci	MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE,
73162306a36Sopenharmony_ci		     (hsize << 16) + (vsize <<  0), 0x1FFF1FFF);
73262306a36Sopenharmony_ci	return 0;
73362306a36Sopenharmony_ci}
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_cistatic const struct mdp_comp_ops ccorr_ops = {
73662306a36Sopenharmony_ci	.get_comp_flag = get_comp_flag,
73762306a36Sopenharmony_ci	.init_comp = init_ccorr,
73862306a36Sopenharmony_ci	.config_subfrm = config_ccorr_subfrm,
73962306a36Sopenharmony_ci};
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_cistatic const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
74262306a36Sopenharmony_ci	[MDP_COMP_TYPE_RDMA] =		&rdma_ops,
74362306a36Sopenharmony_ci	[MDP_COMP_TYPE_RSZ] =		&rsz_ops,
74462306a36Sopenharmony_ci	[MDP_COMP_TYPE_WROT] =		&wrot_ops,
74562306a36Sopenharmony_ci	[MDP_COMP_TYPE_WDMA] =		&wdma_ops,
74662306a36Sopenharmony_ci	[MDP_COMP_TYPE_CCORR] =		&ccorr_ops,
74762306a36Sopenharmony_ci};
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_cistatic const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
75062306a36Sopenharmony_ci	{
75162306a36Sopenharmony_ci		.compatible = "mediatek,mt8183-mdp3-rdma",
75262306a36Sopenharmony_ci		.data = (void *)MDP_COMP_TYPE_RDMA,
75362306a36Sopenharmony_ci	}, {
75462306a36Sopenharmony_ci		.compatible = "mediatek,mt8183-mdp3-ccorr",
75562306a36Sopenharmony_ci		.data = (void *)MDP_COMP_TYPE_CCORR,
75662306a36Sopenharmony_ci	}, {
75762306a36Sopenharmony_ci		.compatible = "mediatek,mt8183-mdp3-rsz",
75862306a36Sopenharmony_ci		.data = (void *)MDP_COMP_TYPE_RSZ,
75962306a36Sopenharmony_ci	}, {
76062306a36Sopenharmony_ci		.compatible = "mediatek,mt8183-mdp3-wrot",
76162306a36Sopenharmony_ci		.data = (void *)MDP_COMP_TYPE_WROT,
76262306a36Sopenharmony_ci	}, {
76362306a36Sopenharmony_ci		.compatible = "mediatek,mt8183-mdp3-wdma",
76462306a36Sopenharmony_ci		.data = (void *)MDP_COMP_TYPE_WDMA,
76562306a36Sopenharmony_ci	},
76662306a36Sopenharmony_ci	{}
76762306a36Sopenharmony_ci};
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_cistatic inline bool is_dma_capable(const enum mdp_comp_type type)
77062306a36Sopenharmony_ci{
77162306a36Sopenharmony_ci	return (type == MDP_COMP_TYPE_RDMA ||
77262306a36Sopenharmony_ci		type == MDP_COMP_TYPE_WROT ||
77362306a36Sopenharmony_ci		type == MDP_COMP_TYPE_WDMA);
77462306a36Sopenharmony_ci}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_cistatic inline bool is_bypass_gce_event(const enum mdp_comp_type type)
77762306a36Sopenharmony_ci{
77862306a36Sopenharmony_ci	/*
77962306a36Sopenharmony_ci	 * Subcomponent PATH is only used for the direction of data flow and
78062306a36Sopenharmony_ci	 * dose not need to wait for GCE event.
78162306a36Sopenharmony_ci	 */
78262306a36Sopenharmony_ci	return (type == MDP_COMP_TYPE_PATH);
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_cistatic int mdp_comp_get_id(struct mdp_dev *mdp, enum mdp_comp_type type, u32 alias_id)
78662306a36Sopenharmony_ci{
78762306a36Sopenharmony_ci	int i;
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci	for (i = 0; i < mdp->mdp_data->comp_data_len; i++)
79062306a36Sopenharmony_ci		if (mdp->mdp_data->comp_data[i].match.type == type &&
79162306a36Sopenharmony_ci		    mdp->mdp_data->comp_data[i].match.alias_id == alias_id)
79262306a36Sopenharmony_ci			return i;
79362306a36Sopenharmony_ci	return -ENODEV;
79462306a36Sopenharmony_ci}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ciint mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
79762306a36Sopenharmony_ci{
79862306a36Sopenharmony_ci	int i, ret;
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	/* Only DMA capable components need the pm control */
80162306a36Sopenharmony_ci	if (comp->comp_dev && is_dma_capable(comp->type)) {
80262306a36Sopenharmony_ci		ret = pm_runtime_resume_and_get(comp->comp_dev);
80362306a36Sopenharmony_ci		if (ret < 0) {
80462306a36Sopenharmony_ci			dev_err(dev,
80562306a36Sopenharmony_ci				"Failed to get power, err %d. type:%d id:%d\n",
80662306a36Sopenharmony_ci				ret, comp->type, comp->inner_id);
80762306a36Sopenharmony_ci			return ret;
80862306a36Sopenharmony_ci		}
80962306a36Sopenharmony_ci	}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	for (i = 0; i < comp->clk_num; i++) {
81262306a36Sopenharmony_ci		if (IS_ERR_OR_NULL(comp->clks[i]))
81362306a36Sopenharmony_ci			continue;
81462306a36Sopenharmony_ci		ret = clk_prepare_enable(comp->clks[i]);
81562306a36Sopenharmony_ci		if (ret) {
81662306a36Sopenharmony_ci			dev_err(dev,
81762306a36Sopenharmony_ci				"Failed to enable clk %d. type:%d id:%d\n",
81862306a36Sopenharmony_ci				i, comp->type, comp->inner_id);
81962306a36Sopenharmony_ci			goto err_revert;
82062306a36Sopenharmony_ci		}
82162306a36Sopenharmony_ci	}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	return 0;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_cierr_revert:
82662306a36Sopenharmony_ci	while (--i >= 0) {
82762306a36Sopenharmony_ci		if (IS_ERR_OR_NULL(comp->clks[i]))
82862306a36Sopenharmony_ci			continue;
82962306a36Sopenharmony_ci		clk_disable_unprepare(comp->clks[i]);
83062306a36Sopenharmony_ci	}
83162306a36Sopenharmony_ci	if (comp->comp_dev && is_dma_capable(comp->type))
83262306a36Sopenharmony_ci		pm_runtime_put_sync(comp->comp_dev);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	return ret;
83562306a36Sopenharmony_ci}
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_civoid mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
83862306a36Sopenharmony_ci{
83962306a36Sopenharmony_ci	int i;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	for (i = 0; i < comp->clk_num; i++) {
84262306a36Sopenharmony_ci		if (IS_ERR_OR_NULL(comp->clks[i]))
84362306a36Sopenharmony_ci			continue;
84462306a36Sopenharmony_ci		clk_disable_unprepare(comp->clks[i]);
84562306a36Sopenharmony_ci	}
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	if (comp->comp_dev && is_dma_capable(comp->type))
84862306a36Sopenharmony_ci		pm_runtime_put(comp->comp_dev);
84962306a36Sopenharmony_ci}
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ciint mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
85262306a36Sopenharmony_ci{
85362306a36Sopenharmony_ci	int i, ret;
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
85662306a36Sopenharmony_ci		ret = mdp_comp_clock_on(dev, &comps[i]);
85762306a36Sopenharmony_ci		if (ret)
85862306a36Sopenharmony_ci			return ret;
85962306a36Sopenharmony_ci	}
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	return 0;
86262306a36Sopenharmony_ci}
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_civoid mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	int i;
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	for (i = 0; i < num; i++)
86962306a36Sopenharmony_ci		mdp_comp_clock_off(dev, &comps[i]);
87062306a36Sopenharmony_ci}
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_cistatic int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev,
87362306a36Sopenharmony_ci			     struct device_node *node, struct mdp_comp *comp)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci	struct platform_device *comp_pdev;
87662306a36Sopenharmony_ci	struct cmdq_client_reg  cmdq_reg;
87762306a36Sopenharmony_ci	int ret = 0;
87862306a36Sopenharmony_ci	int index = 0;
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	if (!dev || !node || !comp)
88162306a36Sopenharmony_ci		return -EINVAL;
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	comp_pdev = of_find_device_by_node(node);
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci	if (!comp_pdev) {
88662306a36Sopenharmony_ci		dev_err(dev, "get comp_pdev fail! comp public id=%d, inner id=%d, type=%d\n",
88762306a36Sopenharmony_ci			comp->public_id, comp->inner_id, comp->type);
88862306a36Sopenharmony_ci		return -ENODEV;
88962306a36Sopenharmony_ci	}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
89262306a36Sopenharmony_ci	ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
89362306a36Sopenharmony_ci	if (ret != 0) {
89462306a36Sopenharmony_ci		dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
89562306a36Sopenharmony_ci		put_device(&comp_pdev->dev);
89662306a36Sopenharmony_ci		return -EINVAL;
89762306a36Sopenharmony_ci	}
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	comp->subsys_id = cmdq_reg.subsys;
90062306a36Sopenharmony_ci	dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys);
90162306a36Sopenharmony_ci	put_device(&comp_pdev->dev);
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	return 0;
90462306a36Sopenharmony_ci}
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_cistatic void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
90762306a36Sopenharmony_ci			    struct mdp_comp *comp)
90862306a36Sopenharmony_ci{
90962306a36Sopenharmony_ci	struct resource res;
91062306a36Sopenharmony_ci	phys_addr_t base;
91162306a36Sopenharmony_ci	int index;
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
91462306a36Sopenharmony_ci	if (of_address_to_resource(node, index, &res) < 0)
91562306a36Sopenharmony_ci		base = 0L;
91662306a36Sopenharmony_ci	else
91762306a36Sopenharmony_ci		base = res.start;
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci	comp->mdp_dev = mdp;
92062306a36Sopenharmony_ci	comp->regs = of_iomap(node, 0);
92162306a36Sopenharmony_ci	comp->reg_base = base;
92262306a36Sopenharmony_ci}
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_cistatic int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
92562306a36Sopenharmony_ci			 struct mdp_comp *comp, enum mtk_mdp_comp_id id)
92662306a36Sopenharmony_ci{
92762306a36Sopenharmony_ci	struct device *dev = &mdp->pdev->dev;
92862306a36Sopenharmony_ci	struct platform_device *pdev_c;
92962306a36Sopenharmony_ci	int clk_ofst;
93062306a36Sopenharmony_ci	int i;
93162306a36Sopenharmony_ci	s32 event;
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
93462306a36Sopenharmony_ci		dev_err(dev, "Invalid component id %d\n", id);
93562306a36Sopenharmony_ci		return -EINVAL;
93662306a36Sopenharmony_ci	}
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci	pdev_c = of_find_device_by_node(node);
93962306a36Sopenharmony_ci	if (!pdev_c) {
94062306a36Sopenharmony_ci		dev_warn(dev, "can't find platform device of node:%s\n",
94162306a36Sopenharmony_ci			 node->name);
94262306a36Sopenharmony_ci		return -ENODEV;
94362306a36Sopenharmony_ci	}
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	comp->comp_dev = &pdev_c->dev;
94662306a36Sopenharmony_ci	comp->public_id = id;
94762306a36Sopenharmony_ci	comp->type = mdp->mdp_data->comp_data[id].match.type;
94862306a36Sopenharmony_ci	comp->inner_id = mdp->mdp_data->comp_data[id].match.inner_id;
94962306a36Sopenharmony_ci	comp->alias_id = mdp->mdp_data->comp_data[id].match.alias_id;
95062306a36Sopenharmony_ci	comp->ops = mdp_comp_ops[comp->type];
95162306a36Sopenharmony_ci	__mdp_comp_init(mdp, node, comp);
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	comp->clk_num = mdp->mdp_data->comp_data[id].info.clk_num;
95462306a36Sopenharmony_ci	comp->clks = devm_kzalloc(dev, sizeof(struct clk *) * comp->clk_num,
95562306a36Sopenharmony_ci				  GFP_KERNEL);
95662306a36Sopenharmony_ci	if (!comp->clks)
95762306a36Sopenharmony_ci		return -ENOMEM;
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	clk_ofst = mdp->mdp_data->comp_data[id].info.clk_ofst;
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci	for (i = 0; i < comp->clk_num; i++) {
96262306a36Sopenharmony_ci		comp->clks[i] = of_clk_get(node, i + clk_ofst);
96362306a36Sopenharmony_ci		if (IS_ERR(comp->clks[i]))
96462306a36Sopenharmony_ci			break;
96562306a36Sopenharmony_ci	}
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci	mdp_get_subsys_id(mdp, dev, node, comp);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	/* Set GCE SOF event */
97062306a36Sopenharmony_ci	if (is_bypass_gce_event(comp->type) ||
97162306a36Sopenharmony_ci	    of_property_read_u32_index(node, "mediatek,gce-events",
97262306a36Sopenharmony_ci				       MDP_GCE_EVENT_SOF, &event))
97362306a36Sopenharmony_ci		event = MDP_GCE_NO_EVENT;
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	comp->gce_event[MDP_GCE_EVENT_SOF] = event;
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci	/* Set GCE EOF event */
97862306a36Sopenharmony_ci	if (is_dma_capable(comp->type)) {
97962306a36Sopenharmony_ci		if (of_property_read_u32_index(node, "mediatek,gce-events",
98062306a36Sopenharmony_ci					       MDP_GCE_EVENT_EOF, &event)) {
98162306a36Sopenharmony_ci			dev_err(dev, "Component id %d has no EOF\n", id);
98262306a36Sopenharmony_ci			return -EINVAL;
98362306a36Sopenharmony_ci		}
98462306a36Sopenharmony_ci	} else {
98562306a36Sopenharmony_ci		event = MDP_GCE_NO_EVENT;
98662306a36Sopenharmony_ci	}
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	comp->gce_event[MDP_GCE_EVENT_EOF] = event;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	return 0;
99162306a36Sopenharmony_ci}
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_cistatic void mdp_comp_deinit(struct mdp_comp *comp)
99462306a36Sopenharmony_ci{
99562306a36Sopenharmony_ci	if (!comp)
99662306a36Sopenharmony_ci		return;
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	if (comp->comp_dev && comp->clks) {
99962306a36Sopenharmony_ci		devm_kfree(&comp->mdp_dev->pdev->dev, comp->clks);
100062306a36Sopenharmony_ci		comp->clks = NULL;
100162306a36Sopenharmony_ci	}
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	if (comp->regs)
100462306a36Sopenharmony_ci		iounmap(comp->regs);
100562306a36Sopenharmony_ci}
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_cistatic struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
100862306a36Sopenharmony_ci					struct device_node *node,
100962306a36Sopenharmony_ci					enum mtk_mdp_comp_id id)
101062306a36Sopenharmony_ci{
101162306a36Sopenharmony_ci	struct device *dev = &mdp->pdev->dev;
101262306a36Sopenharmony_ci	struct mdp_comp *comp;
101362306a36Sopenharmony_ci	int ret;
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	if (mdp->comp[id])
101662306a36Sopenharmony_ci		return ERR_PTR(-EEXIST);
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
101962306a36Sopenharmony_ci	if (!comp)
102062306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	ret = mdp_comp_init(mdp, node, comp, id);
102362306a36Sopenharmony_ci	if (ret) {
102462306a36Sopenharmony_ci		devm_kfree(dev, comp);
102562306a36Sopenharmony_ci		return ERR_PTR(ret);
102662306a36Sopenharmony_ci	}
102762306a36Sopenharmony_ci	mdp->comp[id] = comp;
102862306a36Sopenharmony_ci	mdp->comp[id]->mdp_dev = mdp;
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	dev_dbg(dev, "%s type:%d alias:%d public id:%d inner id:%d base:%#x regs:%p\n",
103162306a36Sopenharmony_ci		dev->of_node->name, comp->type, comp->alias_id, id, comp->inner_id,
103262306a36Sopenharmony_ci		(u32)comp->reg_base, comp->regs);
103362306a36Sopenharmony_ci	return comp;
103462306a36Sopenharmony_ci}
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_cistatic int mdp_comp_sub_create(struct mdp_dev *mdp)
103762306a36Sopenharmony_ci{
103862306a36Sopenharmony_ci	struct device *dev = &mdp->pdev->dev;
103962306a36Sopenharmony_ci	struct device_node *node, *parent;
104062306a36Sopenharmony_ci	int ret = 0;
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci	parent = dev->of_node->parent;
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	for_each_child_of_node(parent, node) {
104562306a36Sopenharmony_ci		const struct of_device_id *of_id;
104662306a36Sopenharmony_ci		enum mdp_comp_type type;
104762306a36Sopenharmony_ci		int id, alias_id;
104862306a36Sopenharmony_ci		struct mdp_comp *comp;
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci		of_id = of_match_node(mdp->mdp_data->mdp_sub_comp_dt_ids, node);
105162306a36Sopenharmony_ci		if (!of_id)
105262306a36Sopenharmony_ci			continue;
105362306a36Sopenharmony_ci		if (!of_device_is_available(node)) {
105462306a36Sopenharmony_ci			dev_dbg(dev, "Skipping disabled sub comp. %pOF\n",
105562306a36Sopenharmony_ci				node);
105662306a36Sopenharmony_ci			continue;
105762306a36Sopenharmony_ci		}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci		type = (enum mdp_comp_type)(uintptr_t)of_id->data;
106062306a36Sopenharmony_ci		alias_id = mdp_comp_alias_id[type];
106162306a36Sopenharmony_ci		id = mdp_comp_get_id(mdp, type, alias_id);
106262306a36Sopenharmony_ci		if (id < 0) {
106362306a36Sopenharmony_ci			dev_err(dev,
106462306a36Sopenharmony_ci				"Fail to get sub comp. id: type %d alias %d\n",
106562306a36Sopenharmony_ci				type, alias_id);
106662306a36Sopenharmony_ci			ret = -EINVAL;
106762306a36Sopenharmony_ci			goto err_free_node;
106862306a36Sopenharmony_ci		}
106962306a36Sopenharmony_ci		mdp_comp_alias_id[type]++;
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci		comp = mdp_comp_create(mdp, node, id);
107262306a36Sopenharmony_ci		if (IS_ERR(comp)) {
107362306a36Sopenharmony_ci			ret = PTR_ERR(comp);
107462306a36Sopenharmony_ci			goto err_free_node;
107562306a36Sopenharmony_ci		}
107662306a36Sopenharmony_ci	}
107762306a36Sopenharmony_ci	return ret;
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_cierr_free_node:
108062306a36Sopenharmony_ci	of_node_put(node);
108162306a36Sopenharmony_ci	return ret;
108262306a36Sopenharmony_ci}
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_civoid mdp_comp_destroy(struct mdp_dev *mdp)
108562306a36Sopenharmony_ci{
108662306a36Sopenharmony_ci	int i;
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) {
108962306a36Sopenharmony_ci		if (mdp->comp[i]) {
109062306a36Sopenharmony_ci			if (is_dma_capable(mdp->comp[i]->type))
109162306a36Sopenharmony_ci				pm_runtime_disable(mdp->comp[i]->comp_dev);
109262306a36Sopenharmony_ci			mdp_comp_deinit(mdp->comp[i]);
109362306a36Sopenharmony_ci			devm_kfree(mdp->comp[i]->comp_dev, mdp->comp[i]);
109462306a36Sopenharmony_ci			mdp->comp[i] = NULL;
109562306a36Sopenharmony_ci		}
109662306a36Sopenharmony_ci	}
109762306a36Sopenharmony_ci}
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_ciint mdp_comp_config(struct mdp_dev *mdp)
110062306a36Sopenharmony_ci{
110162306a36Sopenharmony_ci	struct device *dev = &mdp->pdev->dev;
110262306a36Sopenharmony_ci	struct device_node *node, *parent;
110362306a36Sopenharmony_ci	int ret;
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci	memset(mdp_comp_alias_id, 0, sizeof(mdp_comp_alias_id));
110662306a36Sopenharmony_ci	p_id = mdp->mdp_data->mdp_plat_id;
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	parent = dev->of_node->parent;
110962306a36Sopenharmony_ci	/* Iterate over sibling MDP function blocks */
111062306a36Sopenharmony_ci	for_each_child_of_node(parent, node) {
111162306a36Sopenharmony_ci		const struct of_device_id *of_id;
111262306a36Sopenharmony_ci		enum mdp_comp_type type;
111362306a36Sopenharmony_ci		int id, alias_id;
111462306a36Sopenharmony_ci		struct mdp_comp *comp;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci		of_id = of_match_node(mdp_comp_dt_ids, node);
111762306a36Sopenharmony_ci		if (!of_id)
111862306a36Sopenharmony_ci			continue;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci		if (!of_device_is_available(node)) {
112162306a36Sopenharmony_ci			dev_dbg(dev, "Skipping disabled component %pOF\n",
112262306a36Sopenharmony_ci				node);
112362306a36Sopenharmony_ci			continue;
112462306a36Sopenharmony_ci		}
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci		type = (enum mdp_comp_type)(uintptr_t)of_id->data;
112762306a36Sopenharmony_ci		alias_id = mdp_comp_alias_id[type];
112862306a36Sopenharmony_ci		id = mdp_comp_get_id(mdp, type, alias_id);
112962306a36Sopenharmony_ci		if (id < 0) {
113062306a36Sopenharmony_ci			dev_err(dev,
113162306a36Sopenharmony_ci				"Fail to get component id: type %d alias %d\n",
113262306a36Sopenharmony_ci				type, alias_id);
113362306a36Sopenharmony_ci			continue;
113462306a36Sopenharmony_ci		}
113562306a36Sopenharmony_ci		mdp_comp_alias_id[type]++;
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci		comp = mdp_comp_create(mdp, node, id);
113862306a36Sopenharmony_ci		if (IS_ERR(comp)) {
113962306a36Sopenharmony_ci			ret = PTR_ERR(comp);
114062306a36Sopenharmony_ci			goto err_init_comps;
114162306a36Sopenharmony_ci		}
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci		/* Only DMA capable components need the pm control */
114462306a36Sopenharmony_ci		if (!is_dma_capable(comp->type))
114562306a36Sopenharmony_ci			continue;
114662306a36Sopenharmony_ci		pm_runtime_enable(comp->comp_dev);
114762306a36Sopenharmony_ci	}
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	ret = mdp_comp_sub_create(mdp);
115062306a36Sopenharmony_ci	if (ret)
115162306a36Sopenharmony_ci		goto err_init_comps;
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci	return 0;
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_cierr_init_comps:
115662306a36Sopenharmony_ci	mdp_comp_destroy(mdp);
115762306a36Sopenharmony_ci	return ret;
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ciint mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
116162306a36Sopenharmony_ci			const struct img_compparam *param,
116262306a36Sopenharmony_ci			const struct img_ipi_frameparam *frame)
116362306a36Sopenharmony_ci{
116462306a36Sopenharmony_ci	struct device *dev = &mdp->pdev->dev;
116562306a36Sopenharmony_ci	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
116662306a36Sopenharmony_ci	u32 arg;
116762306a36Sopenharmony_ci	int i, idx;
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	if (!param) {
117062306a36Sopenharmony_ci		dev_err(dev, "Invalid component param");
117162306a36Sopenharmony_ci		return -EINVAL;
117262306a36Sopenharmony_ci	}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
117562306a36Sopenharmony_ci		arg = CFG_COMP(MT8183, param, type);
117662306a36Sopenharmony_ci	else
117762306a36Sopenharmony_ci		return -EINVAL;
117862306a36Sopenharmony_ci	public_id = mdp_cfg_get_id_public(mdp, arg);
117962306a36Sopenharmony_ci	if (public_id < 0) {
118062306a36Sopenharmony_ci		dev_err(dev, "Invalid component id %d", public_id);
118162306a36Sopenharmony_ci		return -EINVAL;
118262306a36Sopenharmony_ci	}
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	ctx->comp = mdp->comp[public_id];
118562306a36Sopenharmony_ci	if (!ctx->comp) {
118662306a36Sopenharmony_ci		dev_err(dev, "Uninit component inner id %d", arg);
118762306a36Sopenharmony_ci		return -EINVAL;
118862306a36Sopenharmony_ci	}
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	ctx->param = param;
119162306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
119262306a36Sopenharmony_ci		arg = CFG_COMP(MT8183, param, input);
119362306a36Sopenharmony_ci	else
119462306a36Sopenharmony_ci		return -EINVAL;
119562306a36Sopenharmony_ci	ctx->input = &frame->inputs[arg];
119662306a36Sopenharmony_ci	if (CFG_CHECK(MT8183, p_id))
119762306a36Sopenharmony_ci		idx = CFG_COMP(MT8183, param, num_outputs);
119862306a36Sopenharmony_ci	else
119962306a36Sopenharmony_ci		return -EINVAL;
120062306a36Sopenharmony_ci	for (i = 0; i < idx; i++) {
120162306a36Sopenharmony_ci		if (CFG_CHECK(MT8183, p_id))
120262306a36Sopenharmony_ci			arg = CFG_COMP(MT8183, param, outputs[i]);
120362306a36Sopenharmony_ci		else
120462306a36Sopenharmony_ci			return -EINVAL;
120562306a36Sopenharmony_ci		ctx->outputs[i] = &frame->outputs[arg];
120662306a36Sopenharmony_ci	}
120762306a36Sopenharmony_ci	return 0;
120862306a36Sopenharmony_ci}
1209