161890ccaSMoudy Ho // SPDX-License-Identifier: GPL-2.0-only
261890ccaSMoudy Ho /*
361890ccaSMoudy Ho * Copyright (c) 2022 MediaTek Inc.
461890ccaSMoudy Ho * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
561890ccaSMoudy Ho */
661890ccaSMoudy Ho
761890ccaSMoudy Ho #include <linux/clk.h>
861890ccaSMoudy Ho #include <linux/of_platform.h>
961890ccaSMoudy Ho #include <linux/of_address.h>
1061890ccaSMoudy Ho #include <linux/pm_runtime.h>
11b59ed26fSMoudy Ho #include "mtk-mdp3-cfg.h"
1261890ccaSMoudy Ho #include "mtk-mdp3-comp.h"
1361890ccaSMoudy Ho #include "mtk-mdp3-core.h"
1461890ccaSMoudy Ho #include "mtk-mdp3-regs.h"
1561890ccaSMoudy Ho
1661890ccaSMoudy Ho #include "mdp_reg_rdma.h"
1761890ccaSMoudy Ho #include "mdp_reg_ccorr.h"
1861890ccaSMoudy Ho #include "mdp_reg_rsz.h"
1961890ccaSMoudy Ho #include "mdp_reg_wrot.h"
2061890ccaSMoudy Ho #include "mdp_reg_wdma.h"
2161890ccaSMoudy Ho
2261890ccaSMoudy Ho static u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT];
2309e694f1SMoudy Ho static int p_id;
2461890ccaSMoudy Ho
2561890ccaSMoudy Ho static inline const struct mdp_platform_config *
__get_plat_cfg(const struct mdp_comp_ctx * ctx)2661890ccaSMoudy Ho __get_plat_cfg(const struct mdp_comp_ctx *ctx)
2761890ccaSMoudy Ho {
2861890ccaSMoudy Ho if (!ctx)
2961890ccaSMoudy Ho return NULL;
3061890ccaSMoudy Ho
3161890ccaSMoudy Ho return ctx->comp->mdp_dev->mdp_data->mdp_cfg;
3261890ccaSMoudy Ho }
3361890ccaSMoudy Ho
get_comp_flag(const struct mdp_comp_ctx * ctx)3461890ccaSMoudy Ho static s64 get_comp_flag(const struct mdp_comp_ctx *ctx)
3561890ccaSMoudy Ho {
3661890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
37b59ed26fSMoudy Ho u32 rdma0, rsz1;
38b59ed26fSMoudy Ho
39b59ed26fSMoudy Ho rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
40b59ed26fSMoudy Ho rsz1 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RSZ1);
41b59ed26fSMoudy Ho if (!rdma0 || !rsz1)
42b59ed26fSMoudy Ho return MDP_COMP_NONE;
4361890ccaSMoudy Ho
4461890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing)
45b59ed26fSMoudy Ho if (ctx->comp->inner_id == rdma0)
46b59ed26fSMoudy Ho return BIT(rdma0) | BIT(rsz1);
4761890ccaSMoudy Ho
48b59ed26fSMoudy Ho return BIT(ctx->comp->inner_id);
4961890ccaSMoudy Ho }
5061890ccaSMoudy Ho
init_rdma(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)5161890ccaSMoudy Ho static int init_rdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
5261890ccaSMoudy Ho {
5361890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
5461890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
5561890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
56b59ed26fSMoudy Ho s32 rdma0;
57b59ed26fSMoudy Ho
58b59ed26fSMoudy Ho rdma0 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
59b59ed26fSMoudy Ho if (!rdma0)
60b59ed26fSMoudy Ho return -EINVAL;
6161890ccaSMoudy Ho
6261890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
6361890ccaSMoudy Ho struct mdp_comp *prz1 = ctx->comp->mdp_dev->comp[MDP_COMP_RSZ1];
6461890ccaSMoudy Ho
6561890ccaSMoudy Ho /* Disable RSZ1 */
66b59ed26fSMoudy Ho if (ctx->comp->inner_id == rdma0 && prz1)
6761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE,
6861890ccaSMoudy Ho 0x0, BIT(0));
6961890ccaSMoudy Ho }
7061890ccaSMoudy Ho
7161890ccaSMoudy Ho /* Reset RDMA */
7261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0));
7361890ccaSMoudy Ho MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8));
7461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0));
7561890ccaSMoudy Ho return 0;
7661890ccaSMoudy Ho }
7761890ccaSMoudy Ho
config_rdma_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)7861890ccaSMoudy Ho static int config_rdma_frame(struct mdp_comp_ctx *ctx,
7961890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd,
8061890ccaSMoudy Ho const struct v4l2_rect *compose)
8161890ccaSMoudy Ho {
8261890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
8361890ccaSMoudy Ho u32 colorformat = ctx->input->buffer.format.colorformat;
8461890ccaSMoudy Ho bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
8561890ccaSMoudy Ho bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
8661890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
8761890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
8809e694f1SMoudy Ho u32 reg = 0;
8961890ccaSMoudy Ho
9061890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
9161890ccaSMoudy Ho if (block10bit)
9261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base,
9361890ccaSMoudy Ho MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7);
9461890ccaSMoudy Ho else
9561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base,
9661890ccaSMoudy Ho MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7);
9761890ccaSMoudy Ho }
9861890ccaSMoudy Ho
9961890ccaSMoudy Ho /* Setup smi control */
10061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON,
10161890ccaSMoudy Ho (7 << 4) + //burst type to 8
10261890ccaSMoudy Ho (1 << 16), //enable pre-ultra
10361890ccaSMoudy Ho 0x00030071);
10461890ccaSMoudy Ho
10561890ccaSMoudy Ho /* Setup source frame info */
10609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
10709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl);
10809e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg,
10961890ccaSMoudy Ho 0x03C8FE0F);
11061890ccaSMoudy Ho
11161890ccaSMoudy Ho if (mdp_cfg)
11261890ccaSMoudy Ho if (mdp_cfg->rdma_support_10bit && en_ufo) {
11361890ccaSMoudy Ho /* Setup source buffer base */
11409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
11509e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y);
11661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
11761890ccaSMoudy Ho base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
11809e694f1SMoudy Ho reg, 0xFFFFFFFF);
11909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
12009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c);
12161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
12261890ccaSMoudy Ho base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
12309e694f1SMoudy Ho reg, 0xFFFFFFFF);
12461890ccaSMoudy Ho /* Set 10bit source frame pitch */
12509e694f1SMoudy Ho if (block10bit) {
12609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
12709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl);
12861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
12961890ccaSMoudy Ho base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
13009e694f1SMoudy Ho reg, 0x001FFFFF);
13109e694f1SMoudy Ho }
13261890ccaSMoudy Ho }
13361890ccaSMoudy Ho
13409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
13509e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.control);
13609e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg,
13761890ccaSMoudy Ho 0x1110);
13861890ccaSMoudy Ho /* Setup source buffer base */
13909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
14009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]);
14109e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg,
14261890ccaSMoudy Ho 0xFFFFFFFF);
14309e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
14409e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]);
14509e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg,
14661890ccaSMoudy Ho 0xFFFFFFFF);
14709e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
14809e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]);
14909e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg,
15061890ccaSMoudy Ho 0xFFFFFFFF);
15161890ccaSMoudy Ho /* Setup source buffer end */
15209e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
15309e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]);
15461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0,
15509e694f1SMoudy Ho reg, 0xFFFFFFFF);
15609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
15709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]);
15861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1,
15909e694f1SMoudy Ho reg, 0xFFFFFFFF);
16009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
16109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]);
16261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2,
16309e694f1SMoudy Ho reg, 0xFFFFFFFF);
16461890ccaSMoudy Ho /* Setup source frame pitch */
16509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
16609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd);
16761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
16809e694f1SMoudy Ho reg, 0x001FFFFF);
16909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
17009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd);
17161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE,
17209e694f1SMoudy Ho reg, 0x001FFFFF);
17361890ccaSMoudy Ho /* Setup color transform */
17409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
17509e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.transform);
17661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
17709e694f1SMoudy Ho reg, 0x0F110000);
17861890ccaSMoudy Ho
17961890ccaSMoudy Ho return 0;
18061890ccaSMoudy Ho }
18161890ccaSMoudy Ho
config_rdma_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)18261890ccaSMoudy Ho static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
18361890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
18461890ccaSMoudy Ho {
18561890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
18661890ccaSMoudy Ho u32 colorformat = ctx->input->buffer.format.colorformat;
18761890ccaSMoudy Ho bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
18861890ccaSMoudy Ho bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
18961890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
19061890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
19109e694f1SMoudy Ho u32 csf_l = 0, csf_r = 0;
19209e694f1SMoudy Ho u32 reg = 0;
19361890ccaSMoudy Ho
19461890ccaSMoudy Ho /* Enable RDMA */
19561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
19661890ccaSMoudy Ho
19761890ccaSMoudy Ho /* Set Y pixel offset */
19809e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
19909e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]);
20061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
20109e694f1SMoudy Ho reg, 0xFFFFFFFF);
20261890ccaSMoudy Ho
20361890ccaSMoudy Ho /* Set 10bit UFO mode */
20409e694f1SMoudy Ho if (mdp_cfg) {
20509e694f1SMoudy Ho if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo) {
20609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
20709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p);
20861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base,
20961890ccaSMoudy Ho MDP_RDMA_SRC_OFFSET_0_P,
21009e694f1SMoudy Ho reg, 0xFFFFFFFF);
21109e694f1SMoudy Ho }
21209e694f1SMoudy Ho }
21361890ccaSMoudy Ho
21461890ccaSMoudy Ho /* Set U pixel offset */
21509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
21609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]);
21761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1,
21809e694f1SMoudy Ho reg, 0xFFFFFFFF);
21961890ccaSMoudy Ho /* Set V pixel offset */
22009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
22109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]);
22261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2,
22309e694f1SMoudy Ho reg, 0xFFFFFFFF);
22461890ccaSMoudy Ho /* Set source size */
22509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
22609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src);
22709e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg,
22861890ccaSMoudy Ho 0x1FFF1FFF);
22961890ccaSMoudy Ho /* Set target size */
23009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
23109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip);
23261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE,
23309e694f1SMoudy Ho reg, 0x1FFF1FFF);
23461890ccaSMoudy Ho /* Set crop offset */
23509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
23609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst);
23761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1,
23809e694f1SMoudy Ho reg, 0x003F001F);
23961890ccaSMoudy Ho
24009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id)) {
24109e694f1SMoudy Ho csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
24209e694f1SMoudy Ho csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
24309e694f1SMoudy Ho }
24461890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only)
24509e694f1SMoudy Ho if ((csf_r - csf_l + 1) > 320)
24661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base,
24761890ccaSMoudy Ho MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2));
24861890ccaSMoudy Ho
24961890ccaSMoudy Ho return 0;
25061890ccaSMoudy Ho }
25161890ccaSMoudy Ho
wait_rdma_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)25261890ccaSMoudy Ho static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
25361890ccaSMoudy Ho {
25461890ccaSMoudy Ho struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
25561890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
25661890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
25761890ccaSMoudy Ho
25861890ccaSMoudy Ho if (ctx->comp->alias_id == 0)
25961890ccaSMoudy Ho MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
26061890ccaSMoudy Ho else
26161890ccaSMoudy Ho dev_err(dev, "Do not support RDMA1_DONE event\n");
26261890ccaSMoudy Ho
26361890ccaSMoudy Ho /* Disable RDMA */
26461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
26561890ccaSMoudy Ho return 0;
26661890ccaSMoudy Ho }
26761890ccaSMoudy Ho
26861890ccaSMoudy Ho static const struct mdp_comp_ops rdma_ops = {
26961890ccaSMoudy Ho .get_comp_flag = get_comp_flag,
27061890ccaSMoudy Ho .init_comp = init_rdma,
27161890ccaSMoudy Ho .config_frame = config_rdma_frame,
27261890ccaSMoudy Ho .config_subfrm = config_rdma_subfrm,
27361890ccaSMoudy Ho .wait_comp_event = wait_rdma_event,
27461890ccaSMoudy Ho };
27561890ccaSMoudy Ho
init_rsz(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)27661890ccaSMoudy Ho static int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
27761890ccaSMoudy Ho {
27861890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
27961890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
28061890ccaSMoudy Ho
28161890ccaSMoudy Ho /* Reset RSZ */
28261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16));
28361890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16));
28461890ccaSMoudy Ho /* Enable RSZ */
28561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0));
28661890ccaSMoudy Ho return 0;
28761890ccaSMoudy Ho }
28861890ccaSMoudy Ho
config_rsz_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)28961890ccaSMoudy Ho static int config_rsz_frame(struct mdp_comp_ctx *ctx,
29061890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd,
29161890ccaSMoudy Ho const struct v4l2_rect *compose)
29261890ccaSMoudy Ho {
29361890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
29461890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
29509e694f1SMoudy Ho bool bypass = FALSE;
29609e694f1SMoudy Ho u32 reg = 0;
29761890ccaSMoudy Ho
29809e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
29909e694f1SMoudy Ho bypass = CFG_COMP(MT8183, ctx->param, frame.bypass);
30009e694f1SMoudy Ho
30109e694f1SMoudy Ho if (bypass) {
30261890ccaSMoudy Ho /* Disable RSZ */
30361890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0));
30461890ccaSMoudy Ho return 0;
30561890ccaSMoudy Ho }
30661890ccaSMoudy Ho
30709e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
30809e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.control1);
30909e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg,
31061890ccaSMoudy Ho 0x03FFFDF3);
31109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
31209e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.control2);
31309e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
31461890ccaSMoudy Ho 0x0FFFC290);
31509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
31609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x);
31761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP,
31809e694f1SMoudy Ho reg, 0x007FFFFF);
31909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
32009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y);
32161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP,
32209e694f1SMoudy Ho reg, 0x007FFFFF);
32361890ccaSMoudy Ho return 0;
32461890ccaSMoudy Ho }
32561890ccaSMoudy Ho
config_rsz_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)32661890ccaSMoudy Ho static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
32761890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
32861890ccaSMoudy Ho {
32961890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
33061890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
33161890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
33209e694f1SMoudy Ho u32 csf_l = 0, csf_r = 0;
33309e694f1SMoudy Ho u32 reg = 0;
33461890ccaSMoudy Ho
33509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
33609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2);
33709e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
33861890ccaSMoudy Ho 0x00003800);
33909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
34009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src);
34109e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg,
34261890ccaSMoudy Ho 0xFFFFFFFF);
34361890ccaSMoudy Ho
34409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id)) {
34509e694f1SMoudy Ho csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
34609e694f1SMoudy Ho csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
34709e694f1SMoudy Ho }
34861890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample)
34909e694f1SMoudy Ho if ((csf_r - csf_l + 1) <= 16)
35061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1,
35161890ccaSMoudy Ho BIT(27), BIT(27));
35261890ccaSMoudy Ho
35309e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
35409e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left);
35561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET,
35609e694f1SMoudy Ho reg, 0xFFFF);
35709e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
35809e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix);
35961890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
36061890ccaSMoudy Ho base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET,
36109e694f1SMoudy Ho reg, 0x1FFFFF);
36209e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
36309e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top);
36461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET,
36509e694f1SMoudy Ho reg, 0xFFFF);
36609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
36709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix);
36861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET,
36909e694f1SMoudy Ho reg, 0x1FFFFF);
37009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
37109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left);
37261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
37361890ccaSMoudy Ho base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET,
37409e694f1SMoudy Ho reg, 0xFFFF);
37509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
37609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix);
37761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id,
37861890ccaSMoudy Ho base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET,
37909e694f1SMoudy Ho reg, 0x1FFFFF);
38061890ccaSMoudy Ho
38109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
38209e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip);
38309e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg,
38461890ccaSMoudy Ho 0xFFFFFFFF);
38561890ccaSMoudy Ho
38661890ccaSMoudy Ho return 0;
38761890ccaSMoudy Ho }
38861890ccaSMoudy Ho
advance_rsz_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)38961890ccaSMoudy Ho static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx,
39061890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
39161890ccaSMoudy Ho {
39261890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
39361890ccaSMoudy Ho
39461890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) {
39561890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
39661890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
39709e694f1SMoudy Ho u32 csf_l = 0, csf_r = 0;
39861890ccaSMoudy Ho
39909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id)) {
40009e694f1SMoudy Ho csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
40109e694f1SMoudy Ho csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
40209e694f1SMoudy Ho }
40309e694f1SMoudy Ho
40409e694f1SMoudy Ho if ((csf_r - csf_l + 1) <= 16)
40561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0,
40661890ccaSMoudy Ho BIT(27));
40761890ccaSMoudy Ho }
40861890ccaSMoudy Ho
40961890ccaSMoudy Ho return 0;
41061890ccaSMoudy Ho }
41161890ccaSMoudy Ho
41261890ccaSMoudy Ho static const struct mdp_comp_ops rsz_ops = {
41361890ccaSMoudy Ho .get_comp_flag = get_comp_flag,
41461890ccaSMoudy Ho .init_comp = init_rsz,
41561890ccaSMoudy Ho .config_frame = config_rsz_frame,
41661890ccaSMoudy Ho .config_subfrm = config_rsz_subfrm,
41761890ccaSMoudy Ho .advance_subfrm = advance_rsz_subfrm,
41861890ccaSMoudy Ho };
41961890ccaSMoudy Ho
init_wrot(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)42061890ccaSMoudy Ho static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
42161890ccaSMoudy Ho {
42261890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
42361890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
42461890ccaSMoudy Ho
42561890ccaSMoudy Ho /* Reset WROT */
42661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0));
42761890ccaSMoudy Ho MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0));
42861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0));
42961890ccaSMoudy Ho MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0));
43061890ccaSMoudy Ho return 0;
43161890ccaSMoudy Ho }
43261890ccaSMoudy Ho
config_wrot_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)43361890ccaSMoudy Ho static int config_wrot_frame(struct mdp_comp_ctx *ctx,
43461890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd,
43561890ccaSMoudy Ho const struct v4l2_rect *compose)
43661890ccaSMoudy Ho {
43761890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
43861890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
43961890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
44009e694f1SMoudy Ho u32 reg = 0;
44161890ccaSMoudy Ho
44261890ccaSMoudy Ho /* Write frame base address */
44309e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
44409e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]);
44509e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg,
44661890ccaSMoudy Ho 0xFFFFFFFF);
44709e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
44809e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]);
44909e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg,
45061890ccaSMoudy Ho 0xFFFFFFFF);
45109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
45209e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]);
45309e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg,
45461890ccaSMoudy Ho 0xFFFFFFFF);
45561890ccaSMoudy Ho /* Write frame related registers */
45609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
45709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.control);
45809e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg,
45961890ccaSMoudy Ho 0xF131510F);
46061890ccaSMoudy Ho /* Write frame Y pitch */
46109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
46209e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]);
46309e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg,
46461890ccaSMoudy Ho 0x0000FFFF);
46561890ccaSMoudy Ho /* Write frame UV pitch */
46609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
46709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]);
46809e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg,
46961890ccaSMoudy Ho 0xFFFF);
47009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
47109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]);
47209e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg,
47361890ccaSMoudy Ho 0xFFFF);
47461890ccaSMoudy Ho /* Write matrix control */
47509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
47609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl);
47709e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3);
47861890ccaSMoudy Ho
47961890ccaSMoudy Ho /* Set the fixed ALPHA as 0xFF */
48061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000,
48161890ccaSMoudy Ho 0xFF000000);
48261890ccaSMoudy Ho /* Set VIDO_EOL_SEL */
48361890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31));
48461890ccaSMoudy Ho /* Set VIDO_FIFO_TEST */
48509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
48609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test);
48709e694f1SMoudy Ho if (reg != 0)
48861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
48909e694f1SMoudy Ho reg, 0xFFF);
49061890ccaSMoudy Ho /* Filter enable */
49109e694f1SMoudy Ho if (mdp_cfg && mdp_cfg->wrot_filter_constraint) {
49209e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
49309e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.filter);
49461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
49509e694f1SMoudy Ho reg, 0x77);
49609e694f1SMoudy Ho }
49761890ccaSMoudy Ho
49861890ccaSMoudy Ho return 0;
49961890ccaSMoudy Ho }
50061890ccaSMoudy Ho
config_wrot_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)50161890ccaSMoudy Ho static int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
50261890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
50361890ccaSMoudy Ho {
50461890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
50561890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
50609e694f1SMoudy Ho u32 reg = 0;
50761890ccaSMoudy Ho
50861890ccaSMoudy Ho /* Write Y pixel offset */
50909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
51009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]);
51161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
51209e694f1SMoudy Ho reg, 0x0FFFFFFF);
51361890ccaSMoudy Ho /* Write U pixel offset */
51409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
51509e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]);
51661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
51709e694f1SMoudy Ho reg, 0x0FFFFFFF);
51861890ccaSMoudy Ho /* Write V pixel offset */
51909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
52009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]);
52161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
52209e694f1SMoudy Ho reg, 0x0FFFFFFF);
52361890ccaSMoudy Ho /* Write source size */
52409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
52509e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src);
52609e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg,
52761890ccaSMoudy Ho 0x1FFF1FFF);
52861890ccaSMoudy Ho /* Write target size */
52909e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
53009e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip);
53109e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg,
53261890ccaSMoudy Ho 0x1FFF1FFF);
53309e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
53409e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst);
53509e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg,
53661890ccaSMoudy Ho 0x1FFF1FFF);
53761890ccaSMoudy Ho
53809e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
53909e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf);
54061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
54109e694f1SMoudy Ho reg, 0x1FFF7F00);
54261890ccaSMoudy Ho
54361890ccaSMoudy Ho /* Enable WROT */
54461890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0));
54561890ccaSMoudy Ho
54661890ccaSMoudy Ho return 0;
54761890ccaSMoudy Ho }
54861890ccaSMoudy Ho
wait_wrot_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)54961890ccaSMoudy Ho static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
55061890ccaSMoudy Ho {
55161890ccaSMoudy Ho const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
55261890ccaSMoudy Ho struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
55361890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
55461890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
55561890ccaSMoudy Ho
55661890ccaSMoudy Ho if (ctx->comp->alias_id == 0)
55761890ccaSMoudy Ho MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
55861890ccaSMoudy Ho else
55961890ccaSMoudy Ho dev_err(dev, "Do not support WROT1_DONE event\n");
56061890ccaSMoudy Ho
56161890ccaSMoudy Ho if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
56261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
56361890ccaSMoudy Ho 0x77);
56461890ccaSMoudy Ho
56561890ccaSMoudy Ho /* Disable WROT */
56661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0));
56761890ccaSMoudy Ho
56861890ccaSMoudy Ho return 0;
56961890ccaSMoudy Ho }
57061890ccaSMoudy Ho
57161890ccaSMoudy Ho static const struct mdp_comp_ops wrot_ops = {
57261890ccaSMoudy Ho .get_comp_flag = get_comp_flag,
57361890ccaSMoudy Ho .init_comp = init_wrot,
57461890ccaSMoudy Ho .config_frame = config_wrot_frame,
57561890ccaSMoudy Ho .config_subfrm = config_wrot_subfrm,
57661890ccaSMoudy Ho .wait_comp_event = wait_wrot_event,
57761890ccaSMoudy Ho };
57861890ccaSMoudy Ho
init_wdma(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)57961890ccaSMoudy Ho static int init_wdma(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
58061890ccaSMoudy Ho {
58161890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
58261890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
58361890ccaSMoudy Ho
58461890ccaSMoudy Ho /* Reset WDMA */
58561890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0));
58661890ccaSMoudy Ho MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0));
58761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0));
58861890ccaSMoudy Ho return 0;
58961890ccaSMoudy Ho }
59061890ccaSMoudy Ho
config_wdma_frame(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,const struct v4l2_rect * compose)59161890ccaSMoudy Ho static int config_wdma_frame(struct mdp_comp_ctx *ctx,
59261890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd,
59361890ccaSMoudy Ho const struct v4l2_rect *compose)
59461890ccaSMoudy Ho {
59561890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
59661890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
59709e694f1SMoudy Ho u32 reg = 0;
59861890ccaSMoudy Ho
59961890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050,
60061890ccaSMoudy Ho 0xFFFFFFFF);
60161890ccaSMoudy Ho
60261890ccaSMoudy Ho /* Setup frame information */
60309e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
60409e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.wdma_cfg);
60509e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, reg,
60661890ccaSMoudy Ho 0x0F01B8F0);
60761890ccaSMoudy Ho /* Setup frame base address */
60809e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
60909e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.iova[0]);
61009e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg,
61161890ccaSMoudy Ho 0xFFFFFFFF);
61209e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
61309e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.iova[1]);
61409e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg,
61561890ccaSMoudy Ho 0xFFFFFFFF);
61609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
61709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.iova[2]);
61809e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg,
61961890ccaSMoudy Ho 0xFFFFFFFF);
62061890ccaSMoudy Ho /* Setup Y pitch */
62109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
62209e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.w_in_byte);
62361890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE,
62409e694f1SMoudy Ho reg, 0x0000FFFF);
62561890ccaSMoudy Ho /* Setup UV pitch */
62609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
62709e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.uv_stride);
62861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH,
62909e694f1SMoudy Ho reg, 0x0000FFFF);
63061890ccaSMoudy Ho /* Set the fixed ALPHA as 0xFF */
63161890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF,
63261890ccaSMoudy Ho 0x800000FF);
63361890ccaSMoudy Ho
63461890ccaSMoudy Ho return 0;
63561890ccaSMoudy Ho }
63661890ccaSMoudy Ho
config_wdma_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)63761890ccaSMoudy Ho static int config_wdma_subfrm(struct mdp_comp_ctx *ctx,
63861890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
63961890ccaSMoudy Ho {
64061890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
64161890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
64209e694f1SMoudy Ho u32 reg = 0;
64361890ccaSMoudy Ho
64461890ccaSMoudy Ho /* Write Y pixel offset */
64509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
64609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[0]);
64761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET,
64809e694f1SMoudy Ho reg, 0x0FFFFFFF);
64961890ccaSMoudy Ho /* Write U pixel offset */
65009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
65109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[1]);
65261890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET,
65309e694f1SMoudy Ho reg, 0x0FFFFFFF);
65461890ccaSMoudy Ho /* Write V pixel offset */
65509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
65609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[2]);
65761890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET,
65809e694f1SMoudy Ho reg, 0x0FFFFFFF);
65961890ccaSMoudy Ho /* Write source size */
66009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
66109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].src);
66209e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, reg,
66361890ccaSMoudy Ho 0x3FFF3FFF);
66461890ccaSMoudy Ho /* Write target size */
66509e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
66609e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip);
66709e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg,
66861890ccaSMoudy Ho 0x3FFF3FFF);
66961890ccaSMoudy Ho /* Write clip offset */
67009e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
67109e694f1SMoudy Ho reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip_ofst);
67209e694f1SMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, reg,
67361890ccaSMoudy Ho 0x3FFF3FFF);
67461890ccaSMoudy Ho
67561890ccaSMoudy Ho /* Enable WDMA */
67661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0));
67761890ccaSMoudy Ho
67861890ccaSMoudy Ho return 0;
67961890ccaSMoudy Ho }
68061890ccaSMoudy Ho
wait_wdma_event(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)68161890ccaSMoudy Ho static int wait_wdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
68261890ccaSMoudy Ho {
68361890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
68461890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
68561890ccaSMoudy Ho
68661890ccaSMoudy Ho MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
68761890ccaSMoudy Ho /* Disable WDMA */
68861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0));
68961890ccaSMoudy Ho return 0;
69061890ccaSMoudy Ho }
69161890ccaSMoudy Ho
69261890ccaSMoudy Ho static const struct mdp_comp_ops wdma_ops = {
69361890ccaSMoudy Ho .get_comp_flag = get_comp_flag,
69461890ccaSMoudy Ho .init_comp = init_wdma,
69561890ccaSMoudy Ho .config_frame = config_wdma_frame,
69661890ccaSMoudy Ho .config_subfrm = config_wdma_subfrm,
69761890ccaSMoudy Ho .wait_comp_event = wait_wdma_event,
69861890ccaSMoudy Ho };
69961890ccaSMoudy Ho
init_ccorr(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd)70061890ccaSMoudy Ho static int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
70161890ccaSMoudy Ho {
70261890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
70361890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
70461890ccaSMoudy Ho
70561890ccaSMoudy Ho /* CCORR enable */
70661890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0));
70761890ccaSMoudy Ho /* Relay mode */
70861890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0));
70961890ccaSMoudy Ho return 0;
71061890ccaSMoudy Ho }
71161890ccaSMoudy Ho
config_ccorr_subfrm(struct mdp_comp_ctx * ctx,struct mdp_cmdq_cmd * cmd,u32 index)71261890ccaSMoudy Ho static int config_ccorr_subfrm(struct mdp_comp_ctx *ctx,
71361890ccaSMoudy Ho struct mdp_cmdq_cmd *cmd, u32 index)
71461890ccaSMoudy Ho {
71561890ccaSMoudy Ho phys_addr_t base = ctx->comp->reg_base;
71661890ccaSMoudy Ho u8 subsys_id = ctx->comp->subsys_id;
71709e694f1SMoudy Ho u32 csf_l = 0, csf_r = 0;
71809e694f1SMoudy Ho u32 csf_t = 0, csf_b = 0;
71961890ccaSMoudy Ho u32 hsize, vsize;
72061890ccaSMoudy Ho
72109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id)) {
72209e694f1SMoudy Ho csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
72309e694f1SMoudy Ho csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
72409e694f1SMoudy Ho csf_t = CFG_COMP(MT8183, ctx->param, subfrms[index].in.top);
72509e694f1SMoudy Ho csf_b = CFG_COMP(MT8183, ctx->param, subfrms[index].in.bottom);
72609e694f1SMoudy Ho }
72709e694f1SMoudy Ho
72809e694f1SMoudy Ho hsize = csf_r - csf_l + 1;
72909e694f1SMoudy Ho vsize = csf_b - csf_t + 1;
73061890ccaSMoudy Ho MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE,
73161890ccaSMoudy Ho (hsize << 16) + (vsize << 0), 0x1FFF1FFF);
73261890ccaSMoudy Ho return 0;
73361890ccaSMoudy Ho }
73461890ccaSMoudy Ho
73561890ccaSMoudy Ho static const struct mdp_comp_ops ccorr_ops = {
73661890ccaSMoudy Ho .get_comp_flag = get_comp_flag,
73761890ccaSMoudy Ho .init_comp = init_ccorr,
73861890ccaSMoudy Ho .config_subfrm = config_ccorr_subfrm,
73961890ccaSMoudy Ho };
74061890ccaSMoudy Ho
74161890ccaSMoudy Ho static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
74261890ccaSMoudy Ho [MDP_COMP_TYPE_RDMA] = &rdma_ops,
74361890ccaSMoudy Ho [MDP_COMP_TYPE_RSZ] = &rsz_ops,
74461890ccaSMoudy Ho [MDP_COMP_TYPE_WROT] = &wrot_ops,
74561890ccaSMoudy Ho [MDP_COMP_TYPE_WDMA] = &wdma_ops,
74661890ccaSMoudy Ho [MDP_COMP_TYPE_CCORR] = &ccorr_ops,
74761890ccaSMoudy Ho };
74861890ccaSMoudy Ho
749243bb45dSKrzysztof Kozlowski static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
75061890ccaSMoudy Ho {
75161890ccaSMoudy Ho .compatible = "mediatek,mt8183-mdp3-rdma",
75261890ccaSMoudy Ho .data = (void *)MDP_COMP_TYPE_RDMA,
75361890ccaSMoudy Ho }, {
75461890ccaSMoudy Ho .compatible = "mediatek,mt8183-mdp3-ccorr",
75561890ccaSMoudy Ho .data = (void *)MDP_COMP_TYPE_CCORR,
75661890ccaSMoudy Ho }, {
75761890ccaSMoudy Ho .compatible = "mediatek,mt8183-mdp3-rsz",
75861890ccaSMoudy Ho .data = (void *)MDP_COMP_TYPE_RSZ,
75961890ccaSMoudy Ho }, {
76061890ccaSMoudy Ho .compatible = "mediatek,mt8183-mdp3-wrot",
76161890ccaSMoudy Ho .data = (void *)MDP_COMP_TYPE_WROT,
76261890ccaSMoudy Ho }, {
76361890ccaSMoudy Ho .compatible = "mediatek,mt8183-mdp3-wdma",
76461890ccaSMoudy Ho .data = (void *)MDP_COMP_TYPE_WDMA,
76561890ccaSMoudy Ho },
76661890ccaSMoudy Ho {}
76761890ccaSMoudy Ho };
76861890ccaSMoudy Ho
is_dma_capable(const enum mdp_comp_type type)76961890ccaSMoudy Ho static inline bool is_dma_capable(const enum mdp_comp_type type)
77061890ccaSMoudy Ho {
77161890ccaSMoudy Ho return (type == MDP_COMP_TYPE_RDMA ||
77261890ccaSMoudy Ho type == MDP_COMP_TYPE_WROT ||
77361890ccaSMoudy Ho type == MDP_COMP_TYPE_WDMA);
77461890ccaSMoudy Ho }
77561890ccaSMoudy Ho
is_bypass_gce_event(const enum mdp_comp_type type)77661890ccaSMoudy Ho static inline bool is_bypass_gce_event(const enum mdp_comp_type type)
77761890ccaSMoudy Ho {
77861890ccaSMoudy Ho /*
77961890ccaSMoudy Ho * Subcomponent PATH is only used for the direction of data flow and
78061890ccaSMoudy Ho * dose not need to wait for GCE event.
78161890ccaSMoudy Ho */
78261890ccaSMoudy Ho return (type == MDP_COMP_TYPE_PATH);
78361890ccaSMoudy Ho }
78461890ccaSMoudy Ho
mdp_comp_get_id(struct mdp_dev * mdp,enum mdp_comp_type type,u32 alias_id)785b59ed26fSMoudy Ho static int mdp_comp_get_id(struct mdp_dev *mdp, enum mdp_comp_type type, u32 alias_id)
78661890ccaSMoudy Ho {
78761890ccaSMoudy Ho int i;
78861890ccaSMoudy Ho
789b59ed26fSMoudy Ho for (i = 0; i < mdp->mdp_data->comp_data_len; i++)
790b59ed26fSMoudy Ho if (mdp->mdp_data->comp_data[i].match.type == type &&
791b59ed26fSMoudy Ho mdp->mdp_data->comp_data[i].match.alias_id == alias_id)
79261890ccaSMoudy Ho return i;
79361890ccaSMoudy Ho return -ENODEV;
79461890ccaSMoudy Ho }
79561890ccaSMoudy Ho
mdp_comp_clock_on(struct device * dev,struct mdp_comp * comp)79661890ccaSMoudy Ho int mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
79761890ccaSMoudy Ho {
79861890ccaSMoudy Ho int i, ret;
79961890ccaSMoudy Ho
800c4320f97SMoudy Ho /* Only DMA capable components need the pm control */
801c4320f97SMoudy Ho if (comp->comp_dev && is_dma_capable(comp->type)) {
802ff464745SSun Ke ret = pm_runtime_resume_and_get(comp->comp_dev);
80361890ccaSMoudy Ho if (ret < 0) {
80461890ccaSMoudy Ho dev_err(dev,
80561890ccaSMoudy Ho "Failed to get power, err %d. type:%d id:%d\n",
806b59ed26fSMoudy Ho ret, comp->type, comp->inner_id);
80761890ccaSMoudy Ho return ret;
80861890ccaSMoudy Ho }
80961890ccaSMoudy Ho }
81061890ccaSMoudy Ho
811c4320f97SMoudy Ho for (i = 0; i < comp->clk_num; i++) {
81261890ccaSMoudy Ho if (IS_ERR_OR_NULL(comp->clks[i]))
81361890ccaSMoudy Ho continue;
81461890ccaSMoudy Ho ret = clk_prepare_enable(comp->clks[i]);
81561890ccaSMoudy Ho if (ret) {
81661890ccaSMoudy Ho dev_err(dev,
81761890ccaSMoudy Ho "Failed to enable clk %d. type:%d id:%d\n",
818b59ed26fSMoudy Ho i, comp->type, comp->inner_id);
81974a596e7SMoudy Ho goto err_revert;
82061890ccaSMoudy Ho }
82161890ccaSMoudy Ho }
82261890ccaSMoudy Ho
82361890ccaSMoudy Ho return 0;
82474a596e7SMoudy Ho
82574a596e7SMoudy Ho err_revert:
82674a596e7SMoudy Ho while (--i >= 0) {
82774a596e7SMoudy Ho if (IS_ERR_OR_NULL(comp->clks[i]))
82874a596e7SMoudy Ho continue;
82974a596e7SMoudy Ho clk_disable_unprepare(comp->clks[i]);
83074a596e7SMoudy Ho }
831c4320f97SMoudy Ho if (comp->comp_dev && is_dma_capable(comp->type))
83274a596e7SMoudy Ho pm_runtime_put_sync(comp->comp_dev);
83374a596e7SMoudy Ho
83474a596e7SMoudy Ho return ret;
83561890ccaSMoudy Ho }
83661890ccaSMoudy Ho
mdp_comp_clock_off(struct device * dev,struct mdp_comp * comp)83761890ccaSMoudy Ho void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
83861890ccaSMoudy Ho {
83961890ccaSMoudy Ho int i;
84061890ccaSMoudy Ho
841c4320f97SMoudy Ho for (i = 0; i < comp->clk_num; i++) {
84261890ccaSMoudy Ho if (IS_ERR_OR_NULL(comp->clks[i]))
84361890ccaSMoudy Ho continue;
84461890ccaSMoudy Ho clk_disable_unprepare(comp->clks[i]);
84561890ccaSMoudy Ho }
84661890ccaSMoudy Ho
847c4320f97SMoudy Ho if (comp->comp_dev && is_dma_capable(comp->type))
84861890ccaSMoudy Ho pm_runtime_put(comp->comp_dev);
84961890ccaSMoudy Ho }
85061890ccaSMoudy Ho
mdp_comp_clocks_on(struct device * dev,struct mdp_comp * comps,int num)85161890ccaSMoudy Ho int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
85261890ccaSMoudy Ho {
85374a596e7SMoudy Ho int i, ret;
85461890ccaSMoudy Ho
85574a596e7SMoudy Ho for (i = 0; i < num; i++) {
85674a596e7SMoudy Ho ret = mdp_comp_clock_on(dev, &comps[i]);
85774a596e7SMoudy Ho if (ret)
85874a596e7SMoudy Ho return ret;
85974a596e7SMoudy Ho }
86061890ccaSMoudy Ho
86161890ccaSMoudy Ho return 0;
86261890ccaSMoudy Ho }
86361890ccaSMoudy Ho
mdp_comp_clocks_off(struct device * dev,struct mdp_comp * comps,int num)86461890ccaSMoudy Ho void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
86561890ccaSMoudy Ho {
86661890ccaSMoudy Ho int i;
86761890ccaSMoudy Ho
86861890ccaSMoudy Ho for (i = 0; i < num; i++)
86961890ccaSMoudy Ho mdp_comp_clock_off(dev, &comps[i]);
87061890ccaSMoudy Ho }
87161890ccaSMoudy Ho
mdp_get_subsys_id(struct mdp_dev * mdp,struct device * dev,struct device_node * node,struct mdp_comp * comp)872b59ed26fSMoudy Ho static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev,
873b59ed26fSMoudy Ho struct device_node *node, struct mdp_comp *comp)
87461890ccaSMoudy Ho {
87561890ccaSMoudy Ho struct platform_device *comp_pdev;
87661890ccaSMoudy Ho struct cmdq_client_reg cmdq_reg;
87761890ccaSMoudy Ho int ret = 0;
87861890ccaSMoudy Ho int index = 0;
87961890ccaSMoudy Ho
88061890ccaSMoudy Ho if (!dev || !node || !comp)
88161890ccaSMoudy Ho return -EINVAL;
88261890ccaSMoudy Ho
88361890ccaSMoudy Ho comp_pdev = of_find_device_by_node(node);
88461890ccaSMoudy Ho
88561890ccaSMoudy Ho if (!comp_pdev) {
886b59ed26fSMoudy Ho dev_err(dev, "get comp_pdev fail! comp public id=%d, inner id=%d, type=%d\n",
887b59ed26fSMoudy Ho comp->public_id, comp->inner_id, comp->type);
88861890ccaSMoudy Ho return -ENODEV;
88961890ccaSMoudy Ho }
89061890ccaSMoudy Ho
891b59ed26fSMoudy Ho index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
89261890ccaSMoudy Ho ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
89361890ccaSMoudy Ho if (ret != 0) {
89461890ccaSMoudy Ho dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
895*35ca8ce4SLu Hongfei put_device(&comp_pdev->dev);
89661890ccaSMoudy Ho return -EINVAL;
89761890ccaSMoudy Ho }
89861890ccaSMoudy Ho
89961890ccaSMoudy Ho comp->subsys_id = cmdq_reg.subsys;
90061890ccaSMoudy Ho dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys);
901*35ca8ce4SLu Hongfei put_device(&comp_pdev->dev);
90261890ccaSMoudy Ho
90361890ccaSMoudy Ho return 0;
90461890ccaSMoudy Ho }
90561890ccaSMoudy Ho
__mdp_comp_init(struct mdp_dev * mdp,struct device_node * node,struct mdp_comp * comp)90661890ccaSMoudy Ho static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
90761890ccaSMoudy Ho struct mdp_comp *comp)
90861890ccaSMoudy Ho {
90961890ccaSMoudy Ho struct resource res;
91061890ccaSMoudy Ho phys_addr_t base;
911b59ed26fSMoudy Ho int index;
91261890ccaSMoudy Ho
913b59ed26fSMoudy Ho index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
91461890ccaSMoudy Ho if (of_address_to_resource(node, index, &res) < 0)
91561890ccaSMoudy Ho base = 0L;
91661890ccaSMoudy Ho else
91761890ccaSMoudy Ho base = res.start;
91861890ccaSMoudy Ho
91961890ccaSMoudy Ho comp->mdp_dev = mdp;
92061890ccaSMoudy Ho comp->regs = of_iomap(node, 0);
92161890ccaSMoudy Ho comp->reg_base = base;
92261890ccaSMoudy Ho }
92361890ccaSMoudy Ho
mdp_comp_init(struct mdp_dev * mdp,struct device_node * node,struct mdp_comp * comp,enum mtk_mdp_comp_id id)92461890ccaSMoudy Ho static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
92561890ccaSMoudy Ho struct mdp_comp *comp, enum mtk_mdp_comp_id id)
92661890ccaSMoudy Ho {
92761890ccaSMoudy Ho struct device *dev = &mdp->pdev->dev;
928c4320f97SMoudy Ho struct platform_device *pdev_c;
92961890ccaSMoudy Ho int clk_ofst;
93061890ccaSMoudy Ho int i;
93161890ccaSMoudy Ho s32 event;
93261890ccaSMoudy Ho
93361890ccaSMoudy Ho if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
93461890ccaSMoudy Ho dev_err(dev, "Invalid component id %d\n", id);
93561890ccaSMoudy Ho return -EINVAL;
93661890ccaSMoudy Ho }
93761890ccaSMoudy Ho
938c4320f97SMoudy Ho pdev_c = of_find_device_by_node(node);
939c4320f97SMoudy Ho if (!pdev_c) {
940c4320f97SMoudy Ho dev_warn(dev, "can't find platform device of node:%s\n",
941c4320f97SMoudy Ho node->name);
942c4320f97SMoudy Ho return -ENODEV;
943c4320f97SMoudy Ho }
944c4320f97SMoudy Ho
945c4320f97SMoudy Ho comp->comp_dev = &pdev_c->dev;
946b59ed26fSMoudy Ho comp->public_id = id;
947b59ed26fSMoudy Ho comp->type = mdp->mdp_data->comp_data[id].match.type;
948b59ed26fSMoudy Ho comp->inner_id = mdp->mdp_data->comp_data[id].match.inner_id;
949b59ed26fSMoudy Ho comp->alias_id = mdp->mdp_data->comp_data[id].match.alias_id;
95061890ccaSMoudy Ho comp->ops = mdp_comp_ops[comp->type];
95161890ccaSMoudy Ho __mdp_comp_init(mdp, node, comp);
95261890ccaSMoudy Ho
953c4320f97SMoudy Ho comp->clk_num = mdp->mdp_data->comp_data[id].info.clk_num;
954c4320f97SMoudy Ho comp->clks = devm_kzalloc(dev, sizeof(struct clk *) * comp->clk_num,
955c4320f97SMoudy Ho GFP_KERNEL);
956c4320f97SMoudy Ho if (!comp->clks)
957c4320f97SMoudy Ho return -ENOMEM;
958c4320f97SMoudy Ho
959b59ed26fSMoudy Ho clk_ofst = mdp->mdp_data->comp_data[id].info.clk_ofst;
96061890ccaSMoudy Ho
961c4320f97SMoudy Ho for (i = 0; i < comp->clk_num; i++) {
96261890ccaSMoudy Ho comp->clks[i] = of_clk_get(node, i + clk_ofst);
96361890ccaSMoudy Ho if (IS_ERR(comp->clks[i]))
96461890ccaSMoudy Ho break;
96561890ccaSMoudy Ho }
96661890ccaSMoudy Ho
967b59ed26fSMoudy Ho mdp_get_subsys_id(mdp, dev, node, comp);
96861890ccaSMoudy Ho
96961890ccaSMoudy Ho /* Set GCE SOF event */
97061890ccaSMoudy Ho if (is_bypass_gce_event(comp->type) ||
97161890ccaSMoudy Ho of_property_read_u32_index(node, "mediatek,gce-events",
97261890ccaSMoudy Ho MDP_GCE_EVENT_SOF, &event))
97361890ccaSMoudy Ho event = MDP_GCE_NO_EVENT;
97461890ccaSMoudy Ho
97561890ccaSMoudy Ho comp->gce_event[MDP_GCE_EVENT_SOF] = event;
97661890ccaSMoudy Ho
97761890ccaSMoudy Ho /* Set GCE EOF event */
97861890ccaSMoudy Ho if (is_dma_capable(comp->type)) {
97961890ccaSMoudy Ho if (of_property_read_u32_index(node, "mediatek,gce-events",
98061890ccaSMoudy Ho MDP_GCE_EVENT_EOF, &event)) {
98161890ccaSMoudy Ho dev_err(dev, "Component id %d has no EOF\n", id);
98261890ccaSMoudy Ho return -EINVAL;
98361890ccaSMoudy Ho }
98461890ccaSMoudy Ho } else {
98561890ccaSMoudy Ho event = MDP_GCE_NO_EVENT;
98661890ccaSMoudy Ho }
98761890ccaSMoudy Ho
98861890ccaSMoudy Ho comp->gce_event[MDP_GCE_EVENT_EOF] = event;
98961890ccaSMoudy Ho
99061890ccaSMoudy Ho return 0;
99161890ccaSMoudy Ho }
99261890ccaSMoudy Ho
mdp_comp_deinit(struct mdp_comp * comp)99361890ccaSMoudy Ho static void mdp_comp_deinit(struct mdp_comp *comp)
99461890ccaSMoudy Ho {
99561890ccaSMoudy Ho if (!comp)
99661890ccaSMoudy Ho return;
99761890ccaSMoudy Ho
998c4320f97SMoudy Ho if (comp->comp_dev && comp->clks) {
999c4320f97SMoudy Ho devm_kfree(&comp->mdp_dev->pdev->dev, comp->clks);
1000c4320f97SMoudy Ho comp->clks = NULL;
1001c4320f97SMoudy Ho }
1002c4320f97SMoudy Ho
100361890ccaSMoudy Ho if (comp->regs)
100461890ccaSMoudy Ho iounmap(comp->regs);
100561890ccaSMoudy Ho }
100661890ccaSMoudy Ho
mdp_comp_create(struct mdp_dev * mdp,struct device_node * node,enum mtk_mdp_comp_id id)100761890ccaSMoudy Ho static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
100861890ccaSMoudy Ho struct device_node *node,
100961890ccaSMoudy Ho enum mtk_mdp_comp_id id)
101061890ccaSMoudy Ho {
101161890ccaSMoudy Ho struct device *dev = &mdp->pdev->dev;
101261890ccaSMoudy Ho struct mdp_comp *comp;
101361890ccaSMoudy Ho int ret;
101461890ccaSMoudy Ho
101561890ccaSMoudy Ho if (mdp->comp[id])
101661890ccaSMoudy Ho return ERR_PTR(-EEXIST);
101761890ccaSMoudy Ho
101861890ccaSMoudy Ho comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
101961890ccaSMoudy Ho if (!comp)
102061890ccaSMoudy Ho return ERR_PTR(-ENOMEM);
102161890ccaSMoudy Ho
102261890ccaSMoudy Ho ret = mdp_comp_init(mdp, node, comp, id);
102361890ccaSMoudy Ho if (ret) {
102474869a88SMoudy Ho devm_kfree(dev, comp);
102561890ccaSMoudy Ho return ERR_PTR(ret);
102661890ccaSMoudy Ho }
102761890ccaSMoudy Ho mdp->comp[id] = comp;
102861890ccaSMoudy Ho mdp->comp[id]->mdp_dev = mdp;
102961890ccaSMoudy Ho
1030b59ed26fSMoudy Ho dev_dbg(dev, "%s type:%d alias:%d public id:%d inner id:%d base:%#x regs:%p\n",
1031b59ed26fSMoudy Ho dev->of_node->name, comp->type, comp->alias_id, id, comp->inner_id,
103261890ccaSMoudy Ho (u32)comp->reg_base, comp->regs);
103361890ccaSMoudy Ho return comp;
103461890ccaSMoudy Ho }
103561890ccaSMoudy Ho
mdp_comp_sub_create(struct mdp_dev * mdp)103661890ccaSMoudy Ho static int mdp_comp_sub_create(struct mdp_dev *mdp)
103761890ccaSMoudy Ho {
103861890ccaSMoudy Ho struct device *dev = &mdp->pdev->dev;
103961890ccaSMoudy Ho struct device_node *node, *parent;
1040b8ed1cebSDeepak R Varma int ret = 0;
104161890ccaSMoudy Ho
104261890ccaSMoudy Ho parent = dev->of_node->parent;
104361890ccaSMoudy Ho
104461890ccaSMoudy Ho for_each_child_of_node(parent, node) {
104561890ccaSMoudy Ho const struct of_device_id *of_id;
104661890ccaSMoudy Ho enum mdp_comp_type type;
104761890ccaSMoudy Ho int id, alias_id;
104861890ccaSMoudy Ho struct mdp_comp *comp;
104961890ccaSMoudy Ho
1050ae3c253fSArnd Bergmann of_id = of_match_node(mdp->mdp_data->mdp_sub_comp_dt_ids, node);
105161890ccaSMoudy Ho if (!of_id)
105261890ccaSMoudy Ho continue;
105361890ccaSMoudy Ho if (!of_device_is_available(node)) {
105461890ccaSMoudy Ho dev_dbg(dev, "Skipping disabled sub comp. %pOF\n",
105561890ccaSMoudy Ho node);
105661890ccaSMoudy Ho continue;
105761890ccaSMoudy Ho }
105861890ccaSMoudy Ho
105961890ccaSMoudy Ho type = (enum mdp_comp_type)(uintptr_t)of_id->data;
106061890ccaSMoudy Ho alias_id = mdp_comp_alias_id[type];
1061b59ed26fSMoudy Ho id = mdp_comp_get_id(mdp, type, alias_id);
106261890ccaSMoudy Ho if (id < 0) {
106361890ccaSMoudy Ho dev_err(dev,
106461890ccaSMoudy Ho "Fail to get sub comp. id: type %d alias %d\n",
106561890ccaSMoudy Ho type, alias_id);
1066b8ed1cebSDeepak R Varma ret = -EINVAL;
1067b8ed1cebSDeepak R Varma goto err_free_node;
106861890ccaSMoudy Ho }
106961890ccaSMoudy Ho mdp_comp_alias_id[type]++;
107061890ccaSMoudy Ho
107161890ccaSMoudy Ho comp = mdp_comp_create(mdp, node, id);
1072b8ed1cebSDeepak R Varma if (IS_ERR(comp)) {
1073b8ed1cebSDeepak R Varma ret = PTR_ERR(comp);
1074b8ed1cebSDeepak R Varma goto err_free_node;
107561890ccaSMoudy Ho }
1076b8ed1cebSDeepak R Varma }
1077b8ed1cebSDeepak R Varma return ret;
107861890ccaSMoudy Ho
1079b8ed1cebSDeepak R Varma err_free_node:
1080b8ed1cebSDeepak R Varma of_node_put(node);
1081b8ed1cebSDeepak R Varma return ret;
108261890ccaSMoudy Ho }
108361890ccaSMoudy Ho
mdp_comp_destroy(struct mdp_dev * mdp)108461890ccaSMoudy Ho void mdp_comp_destroy(struct mdp_dev *mdp)
108561890ccaSMoudy Ho {
108661890ccaSMoudy Ho int i;
108761890ccaSMoudy Ho
108861890ccaSMoudy Ho for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) {
108961890ccaSMoudy Ho if (mdp->comp[i]) {
1090c4320f97SMoudy Ho if (is_dma_capable(mdp->comp[i]->type))
109161890ccaSMoudy Ho pm_runtime_disable(mdp->comp[i]->comp_dev);
109261890ccaSMoudy Ho mdp_comp_deinit(mdp->comp[i]);
1093ff464745SSun Ke devm_kfree(mdp->comp[i]->comp_dev, mdp->comp[i]);
109461890ccaSMoudy Ho mdp->comp[i] = NULL;
109561890ccaSMoudy Ho }
109661890ccaSMoudy Ho }
109761890ccaSMoudy Ho }
109861890ccaSMoudy Ho
mdp_comp_config(struct mdp_dev * mdp)109961890ccaSMoudy Ho int mdp_comp_config(struct mdp_dev *mdp)
110061890ccaSMoudy Ho {
110161890ccaSMoudy Ho struct device *dev = &mdp->pdev->dev;
110261890ccaSMoudy Ho struct device_node *node, *parent;
110361890ccaSMoudy Ho int ret;
110461890ccaSMoudy Ho
110561890ccaSMoudy Ho memset(mdp_comp_alias_id, 0, sizeof(mdp_comp_alias_id));
110609e694f1SMoudy Ho p_id = mdp->mdp_data->mdp_plat_id;
110761890ccaSMoudy Ho
110861890ccaSMoudy Ho parent = dev->of_node->parent;
110961890ccaSMoudy Ho /* Iterate over sibling MDP function blocks */
111061890ccaSMoudy Ho for_each_child_of_node(parent, node) {
111161890ccaSMoudy Ho const struct of_device_id *of_id;
111261890ccaSMoudy Ho enum mdp_comp_type type;
111361890ccaSMoudy Ho int id, alias_id;
111461890ccaSMoudy Ho struct mdp_comp *comp;
111561890ccaSMoudy Ho
111661890ccaSMoudy Ho of_id = of_match_node(mdp_comp_dt_ids, node);
111761890ccaSMoudy Ho if (!of_id)
111861890ccaSMoudy Ho continue;
111961890ccaSMoudy Ho
112061890ccaSMoudy Ho if (!of_device_is_available(node)) {
112161890ccaSMoudy Ho dev_dbg(dev, "Skipping disabled component %pOF\n",
112261890ccaSMoudy Ho node);
112361890ccaSMoudy Ho continue;
112461890ccaSMoudy Ho }
112561890ccaSMoudy Ho
112661890ccaSMoudy Ho type = (enum mdp_comp_type)(uintptr_t)of_id->data;
112761890ccaSMoudy Ho alias_id = mdp_comp_alias_id[type];
1128b59ed26fSMoudy Ho id = mdp_comp_get_id(mdp, type, alias_id);
112961890ccaSMoudy Ho if (id < 0) {
113061890ccaSMoudy Ho dev_err(dev,
113161890ccaSMoudy Ho "Fail to get component id: type %d alias %d\n",
113261890ccaSMoudy Ho type, alias_id);
113361890ccaSMoudy Ho continue;
113461890ccaSMoudy Ho }
113561890ccaSMoudy Ho mdp_comp_alias_id[type]++;
113661890ccaSMoudy Ho
113761890ccaSMoudy Ho comp = mdp_comp_create(mdp, node, id);
113861890ccaSMoudy Ho if (IS_ERR(comp)) {
113961890ccaSMoudy Ho ret = PTR_ERR(comp);
114061890ccaSMoudy Ho goto err_init_comps;
114161890ccaSMoudy Ho }
114261890ccaSMoudy Ho
114361890ccaSMoudy Ho /* Only DMA capable components need the pm control */
114461890ccaSMoudy Ho if (!is_dma_capable(comp->type))
114561890ccaSMoudy Ho continue;
114661890ccaSMoudy Ho pm_runtime_enable(comp->comp_dev);
114761890ccaSMoudy Ho }
114861890ccaSMoudy Ho
114961890ccaSMoudy Ho ret = mdp_comp_sub_create(mdp);
115061890ccaSMoudy Ho if (ret)
115161890ccaSMoudy Ho goto err_init_comps;
115261890ccaSMoudy Ho
115361890ccaSMoudy Ho return 0;
115461890ccaSMoudy Ho
115561890ccaSMoudy Ho err_init_comps:
115661890ccaSMoudy Ho mdp_comp_destroy(mdp);
115761890ccaSMoudy Ho return ret;
115861890ccaSMoudy Ho }
115961890ccaSMoudy Ho
mdp_comp_ctx_config(struct mdp_dev * mdp,struct mdp_comp_ctx * ctx,const struct img_compparam * param,const struct img_ipi_frameparam * frame)116061890ccaSMoudy Ho int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
116161890ccaSMoudy Ho const struct img_compparam *param,
116261890ccaSMoudy Ho const struct img_ipi_frameparam *frame)
116361890ccaSMoudy Ho {
116461890ccaSMoudy Ho struct device *dev = &mdp->pdev->dev;
1165b59ed26fSMoudy Ho enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
116609e694f1SMoudy Ho u32 arg;
116709e694f1SMoudy Ho int i, idx;
116861890ccaSMoudy Ho
116909e694f1SMoudy Ho if (!param) {
117009e694f1SMoudy Ho dev_err(dev, "Invalid component param");
117109e694f1SMoudy Ho return -EINVAL;
117209e694f1SMoudy Ho }
117309e694f1SMoudy Ho
117409e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
117509e694f1SMoudy Ho arg = CFG_COMP(MT8183, param, type);
117609e694f1SMoudy Ho else
117709e694f1SMoudy Ho return -EINVAL;
117809e694f1SMoudy Ho public_id = mdp_cfg_get_id_public(mdp, arg);
1179b59ed26fSMoudy Ho if (public_id < 0) {
1180b59ed26fSMoudy Ho dev_err(dev, "Invalid component id %d", public_id);
118161890ccaSMoudy Ho return -EINVAL;
118261890ccaSMoudy Ho }
118361890ccaSMoudy Ho
1184b59ed26fSMoudy Ho ctx->comp = mdp->comp[public_id];
118561890ccaSMoudy Ho if (!ctx->comp) {
118609e694f1SMoudy Ho dev_err(dev, "Uninit component inner id %d", arg);
118761890ccaSMoudy Ho return -EINVAL;
118861890ccaSMoudy Ho }
118961890ccaSMoudy Ho
119061890ccaSMoudy Ho ctx->param = param;
119109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
119209e694f1SMoudy Ho arg = CFG_COMP(MT8183, param, input);
119309e694f1SMoudy Ho else
119409e694f1SMoudy Ho return -EINVAL;
119509e694f1SMoudy Ho ctx->input = &frame->inputs[arg];
119609e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
119709e694f1SMoudy Ho idx = CFG_COMP(MT8183, param, num_outputs);
119809e694f1SMoudy Ho else
119909e694f1SMoudy Ho return -EINVAL;
120009e694f1SMoudy Ho for (i = 0; i < idx; i++) {
120109e694f1SMoudy Ho if (CFG_CHECK(MT8183, p_id))
120209e694f1SMoudy Ho arg = CFG_COMP(MT8183, param, outputs[i]);
120309e694f1SMoudy Ho else
120409e694f1SMoudy Ho return -EINVAL;
120509e694f1SMoudy Ho ctx->outputs[i] = &frame->outputs[arg];
120609e694f1SMoudy Ho }
120761890ccaSMoudy Ho return 0;
120861890ccaSMoudy Ho }
1209