brintos

brintos / linux-shallow public Read only

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