| From c5fd94c243955fb80a50519c56114831c68088e4 Mon Sep 17 00:00:00 2001 |
| From: Moudy Ho <moudy.ho@mediatek.corp-partner.google.com> |
| Date: Mon, 2 Sep 2024 16:21:00 +0800 |
| Subject: [PATCH] CHROMIUM: media: platform: mediatek: mdp3: add support for |
| ISP direct-linked to MDP |
| |
| Add the relevant components config and control. |
| |
| BUG=b:341019453 |
| TEST=build pass |
| UPSTREAM-TASK=b:368493852 |
| |
| Change-Id: I0c2a47f21e377819a3932ae711fc7bcd64b70cc0 |
| Signed-off-by: Moudy Ho <moudy.ho@mediatek.com> |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/5828733 |
| Reviewed-by: Hsin-Te Yuan <yuanhsinte@chromium.org> |
| Tested-by: Hsin-Te Yuan <yuanhsinte@chromium.org> |
| Commit-Queue: Hsin-Te Yuan <yuanhsinte@chromium.org> |
| --- |
| .../platform/mediatek/mdp3/mdp_cfg_data.c | 77 +++++++- |
| .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 174 +++++++++++++++++- |
| .../platform/mediatek/mdp3/mtk-mdp3-core.h | 7 + |
| 3 files changed, 253 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c |
| index 0b4c50bc17763421d01db323e80475abfd70801e..0035efa0dfe892887a4f6e76008a7c3a83a00d3a 100644 |
| --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c |
| +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c |
| @@ -4,6 +4,7 @@ |
| * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com> |
| */ |
| |
| +#include <dt-bindings/gce/mt8183-gce.h> |
| #include "mtk-img-ipi.h" |
| #include "mtk-mdp3-cfg.h" |
| #include "mtk-mdp3-core.h" |
| @@ -164,6 +165,21 @@ enum mt8195_mdp_comp_id { |
| MT8195_MDP_COMP_VDO1DL1, /* 62 */ |
| }; |
| |
| +enum { |
| + DIP_CQ_THRE0 = 0, |
| + DIP_CQ_THRE1, |
| + DIP_CQ_THRE2, |
| + DIP_CQ_THRE3, |
| + DIP_CQ_THRE4, |
| + DIP_CQ_THRE5, |
| + DIP_CQ_THRE6, |
| + DIP_CQ_THRE7, |
| + DIP_CQ_THRE8, |
| + DIP_CQ_THRE9, |
| + DIP_CQ_THRE10, |
| + DIP_CQ_THRE11, |
| +}; |
| + |
| static const struct of_device_id mt8183_mdp_probe_infra[MDP_INFRA_MAX] = { |
| [MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8183-mmsys" }, |
| [MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8183-disp-mutex" }, |
| @@ -320,11 +336,11 @@ static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = { |
| }, |
| [MDP_COMP_ISP_IMGI] = { |
| {MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI, MDP_MM_SUBSYS_0}, |
| - {0, 0, 4} |
| + {0, 0, 0} |
| }, |
| [MDP_COMP_ISP_IMGO] = { |
| {MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO, MDP_MM_SUBSYS_0}, |
| - {0, 0, 4} |
| + {0, 0, 0} |
| }, |
| [MDP_COMP_ISP_IMG2O] = { |
| {MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O, MDP_MM_SUBSYS_0}, |
| @@ -332,11 +348,11 @@ static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = { |
| }, |
| [MDP_COMP_CAMIN] = { |
| {MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0}, |
| - {2, 2, 1} |
| + {2, 0, 0} |
| }, |
| [MDP_COMP_CAMIN2] = { |
| {MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0}, |
| - {2, 4, 1} |
| + {2, 2, 0} |
| }, |
| [MDP_COMP_RDMA0] = { |
| {MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0}, |
| @@ -805,6 +821,18 @@ static const struct of_device_id mt8183_sub_comp_dt_ids[] = { |
| }, { |
| .compatible = "mediatek,mt8183-mdp3-wrot", |
| .data = (void *)MDP_COMP_TYPE_PATH, |
| + }, { |
| + .compatible = "mediatek,mt8183-mdp3-imgi", |
| + .data = (void *)MDP_COMP_TYPE_IMGI, |
| + }, { |
| + .compatible = "mediatek,mt8183-mdp3-exto", |
| + .data = (void *)MDP_COMP_TYPE_EXTO, |
| + }, { |
| + .compatible = "mediatek,mt8183-mdp3-dl1", |
| + .data = (void *)MDP_COMP_TYPE_DL_PATH, |
| + }, { |
| + .compatible = "mediatek,mt8183-mdp3-dl2", |
| + .data = (void *)MDP_COMP_TYPE_DL_PATH, |
| }, |
| {} |
| }; |
| @@ -1327,6 +1355,45 @@ static const struct v4l2_rect mt8195_mdp_pp_criteria = { |
| .height = 1080, |
| }; |
| |
| +static const struct mdp_dip_cq_data mt8183_dip_cb[] = { |
| + [DIP_CQ_THRE0] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_0, 0x2208 |
| + }, |
| + [DIP_CQ_THRE1] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_1, 0x2214 |
| + }, |
| + [DIP_CQ_THRE2] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_2, 0x2220 |
| + }, |
| + [DIP_CQ_THRE3] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_3, 0x222C |
| + }, |
| + [DIP_CQ_THRE4] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_4, 0x2238 |
| + }, |
| + [DIP_CQ_THRE5] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_5, 0x2244 |
| + }, |
| + [DIP_CQ_THRE6] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_6, 0x2250 |
| + }, |
| + [DIP_CQ_THRE7] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_7, 0x225C |
| + }, |
| + [DIP_CQ_THRE8] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_8, 0x2268 |
| + }, |
| + [DIP_CQ_THRE9] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_9, 0x2274 |
| + }, |
| + [DIP_CQ_THRE10] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_10, 0x2280 |
| + }, |
| + [DIP_CQ_THRE11] = { |
| + CMDQ_EVENT_ISP_FRAME_DONE_P2_11, 0x228C |
| + }, |
| +}; |
| + |
| const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { |
| .mdp_plat_id = MT8183, |
| .mdp_con_res = 0x14001000, |
| @@ -1342,6 +1409,8 @@ const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { |
| .pipe_info = mt8183_pipe_info, |
| .pipe_info_len = ARRAY_SIZE(mt8183_pipe_info), |
| .pp_used = MDP_PP_USED_1, |
| + .dip_cq_data = mt8183_dip_cb, |
| + .dip_cq_len = ARRAY_SIZE(mt8183_dip_cb), |
| }; |
| |
| const struct mtk_mdp_driver_data mt8188_mdp_driver_data = { |
| diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c |
| index 8f62fb167156ddcc472ee82d554ae8d54f24b0b3..29868daf5157caa9fbcd84745e9501b7d42ceae2 100644 |
| --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c |
| +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c |
| @@ -1524,6 +1524,173 @@ static const struct mdp_comp_ops pad_ops = { |
| .config_subfrm = config_pad_subfrm, |
| }; |
| |
| +static int init_isp(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) |
| +{ |
| + struct device *dev = ctx->comp->mdp_dev->mdp_mmsys; |
| + u32 c_id, c1, c2; |
| + |
| + if (CFG_CHECK(MT8183, p_id)) |
| + c_id = CFG_COMP(MT8183, ctx->param, isp.dl_flags); |
| + else |
| + return 0; |
| + |
| + c1 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_CAMIN); |
| + c2 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_CAMIN2); |
| + |
| + /* Direct link */ |
| + if (c_id & BIT(c1)) { |
| + dev_dbg(dev, "SW_RST ASYNC CAMIN %d", ISP_CTRL_CAM1); |
| + mtk_mmsys_mdp_isp_ctrl(dev, &cmd->pkt, ISP_CTRL_CAM1); |
| + } |
| + if (c_id & BIT(c2)) { |
| + dev_dbg(dev, "SW_RST ASYNC CAMIN %d", ISP_CTRL_CAM2); |
| + mtk_mmsys_mdp_isp_ctrl(dev, &cmd->pkt, ISP_CTRL_CAM2); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static int config_isp_frame(struct mdp_comp_ctx *ctx, |
| + struct mdp_cmdq_cmd *cmd, |
| + const struct v4l2_rect *compose) |
| +{ |
| + struct device *dev = &ctx->comp->mdp_dev->pdev->dev; |
| + struct mdp_dev *m_dev = ctx->comp->mdp_dev; |
| + const struct mdp_dip_cq_data *dip_cq = m_dev->mdp_data->dip_cq_data; |
| + phys_addr_t base = ctx->comp->reg_base; |
| + u8 subsys_id = ctx->comp->subsys_id; |
| + u32 idx; |
| + u32 reg = 0, ofst = 0; |
| + |
| + if (!CFG_CHECK(MT8183, p_id)) |
| + return 0; |
| + |
| + /* DIP_X_SMX1I_BASE_ADDR, DIP_X_SMX1O_BASE_ADDR */ |
| + reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[0]); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2890, reg, 0xFFFFFFFF); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x27D0, reg, 0xFFFFFFFF); |
| + |
| + /* DIP_X_SMX2I_BASE_ADDR, DIP_X_SMX2O_BASE_ADDR */ |
| + reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[1]); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x28C0, reg, 0xFFFFFFFF); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2800, reg, 0xFFFFFFFF); |
| + |
| + /* DIP_X_SMX3I_BASE_ADDR, DIP_X_SMX3O_BASE_ADDR */ |
| + reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[2]); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x28F0, reg, 0xFFFFFFFF); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2830, reg, 0xFFFFFFFF); |
| + |
| + /* DIP_X_SMX4I_BASE_ADDR, DIP_X_SMX4O_BASE_ADDR */ |
| + reg = CFG_COMP(MT8183, ctx->param, isp.smxi_iova[3]); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2920, reg, 0xFFFFFFFF); |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2860, reg, 0xFFFFFFFF); |
| + |
| + idx = CFG_COMP(MT8183, ctx->param, isp.cq_idx); |
| + if (idx >= m_dev->mdp_data->dip_cq_len) { |
| + dev_err(dev, "Do not support this cq (%d)", idx); |
| + return -EINVAL; |
| + } |
| + |
| + reg = CFG_COMP(MT8183, ctx->param, isp.cq_iova); |
| + ofst = dip_cq[idx].frm_ofst; |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, ofst, reg, 0xFFFFFFFF); |
| + |
| + return 0; |
| +} |
| + |
| +static int config_isp_subfrm(struct mdp_comp_ctx *ctx, |
| + struct mdp_cmdq_cmd *cmd, u32 index) |
| +{ |
| + phys_addr_t base = ctx->comp->reg_base; |
| + u8 subsys_id = ctx->comp->subsys_id; |
| + u32 reg; |
| + |
| + if (CFG_CHECK(MT8183, p_id)) |
| + reg = CFG_COMP(MT8183, ctx->param, isp.tpipe_iova[index]); |
| + else |
| + return 0; |
| + |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2304, reg, 0xFFFFFFFF); |
| + |
| + return 0; |
| +} |
| + |
| +static int wait_isp_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) |
| +{ |
| + struct device *dev = &ctx->comp->mdp_dev->pdev->dev; |
| + struct mdp_dev *m_dev = ctx->comp->mdp_dev; |
| + const struct mdp_dip_cq_data *dip_cq = m_dev->mdp_data->dip_cq_data; |
| + phys_addr_t base = ctx->comp->reg_base; |
| + u8 subsys_id = ctx->comp->subsys_id; |
| + u32 c_id, c1, c2; |
| + u32 idx, evt; |
| + |
| + if (CFG_CHECK(MT8183, p_id)) |
| + c_id = CFG_COMP(MT8183, ctx->param, isp.dl_flags); |
| + else |
| + return 0; |
| + |
| + c1 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_CAMIN); |
| + c2 = mdp_cfg_get_id_inner(ctx->comp->mdp_dev, MDP_COMP_CAMIN2); |
| + |
| + /* MDP_DL_SEL: select MDP_CROP */ |
| + if (c_id & BIT(c1)) |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0, |
| + BIT(9)); |
| + if (c_id & BIT(c2)) |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0, |
| + BIT(10) | BIT(11)); |
| + |
| + idx = CFG_COMP(MT8183, ctx->param, isp.cq_idx); |
| + if (idx >= m_dev->mdp_data->dip_cq_len) { |
| + dev_err(dev, "Do not support this cq (%d)", idx); |
| + return -EINVAL; |
| + } |
| + evt = dip_cq[idx].event_id; |
| + |
| + MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(idx), BIT(idx)); |
| + MM_REG_WAIT(cmd, evt); |
| + |
| + return 0; |
| +} |
| + |
| +static const struct mdp_comp_ops imgi_ops = { |
| + .get_comp_flag = get_comp_flag, |
| + .init_comp = init_isp, |
| + .config_frame = config_isp_frame, |
| + .config_subfrm = config_isp_subfrm, |
| + .wait_comp_event = wait_isp_event, |
| +}; |
| + |
| +static int config_camin_subfrm(struct mdp_comp_ctx *ctx, |
| + struct mdp_cmdq_cmd *cmd, u32 index) |
| +{ |
| + struct device *dev = ctx->comp->mdp_dev->mdp_mmsys; |
| + u32 csf_l = 0, csf_r = 0; |
| + u32 csf_t = 0, csf_b = 0; |
| + u32 camin_w, camin_h; |
| + u32 idx; |
| + |
| + csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); |
| + csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right); |
| + csf_t = CFG_COMP(MT8183, ctx->param, subfrms[index].in.top); |
| + csf_b = CFG_COMP(MT8183, ctx->param, subfrms[index].in.bottom); |
| + |
| + camin_w = csf_r - csf_l + 1; |
| + camin_h = csf_b - csf_t + 1; |
| + |
| + /* Config for direct link */ |
| + idx = ctx->comp->alias_id; |
| + mtk_mmsys_mdp_camin_ctrl(dev, &cmd->pkt, idx, camin_w, camin_h); |
| + |
| + return 0; |
| +} |
| + |
| +static const struct mdp_comp_ops camin_ops = { |
| + .get_comp_flag = get_comp_flag, |
| + .config_subfrm = config_camin_subfrm, |
| +}; |
| + |
| static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = { |
| [MDP_COMP_TYPE_RDMA] = &rdma_ops, |
| [MDP_COMP_TYPE_RSZ] = &rsz_ops, |
| @@ -1537,6 +1704,8 @@ static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = { |
| [MDP_COMP_TYPE_FG] = &fg_ops, |
| [MDP_COMP_TYPE_OVL] = &ovl_ops, |
| [MDP_COMP_TYPE_PAD] = &pad_ops, |
| + [MDP_COMP_TYPE_IMGI] = &imgi_ops, |
| + [MDP_COMP_TYPE_DL_PATH] = &camin_ops, |
| }; |
| |
| static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = { |
| @@ -1608,7 +1777,10 @@ static inline bool is_bypass_gce_event(const enum mdp_comp_type type) |
| * Subcomponent PATH is only used for the direction of data flow and |
| * dose not need to wait for GCE event. |
| */ |
| - return (type == MDP_COMP_TYPE_PATH); |
| + return (type == MDP_COMP_TYPE_PATH || |
| + type == MDP_COMP_TYPE_IMGI || |
| + type == MDP_COMP_TYPE_EXTO || |
| + type == MDP_COMP_TYPE_DL_PATH); |
| } |
| |
| static int mdp_comp_get_id(struct mdp_dev *mdp, enum mdp_comp_type type, u32 alias_id) |
| diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h |
| index 430251f63754c999e23fe323ff1a2fa8f5b1d648..d71f989b9e895fcd37b263da2cf74de3f7ac54a3 100644 |
| --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h |
| +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h |
| @@ -101,6 +101,8 @@ struct mtk_mdp_driver_data { |
| unsigned int pipe_info_len; |
| const struct v4l2_rect *pp_criteria; |
| const u8 pp_used; |
| + const struct mdp_dip_cq_data *dip_cq_data; |
| + unsigned int dip_cq_len; |
| }; |
| |
| struct mdp_mm_subsys { |
| @@ -143,6 +145,11 @@ struct mdp_pipe_info { |
| u32 mutex_id; |
| }; |
| |
| +struct mdp_dip_cq_data { |
| + u32 event_id; |
| + u32 frm_ofst; |
| +}; |
| + |
| int mdp_vpu_get_locked(struct mdp_dev *mdp); |
| void mdp_vpu_put_locked(struct mdp_dev *mdp); |
| int mdp_vpu_register(struct mdp_dev *mdp); |
| -- |
| 2.47.0.163.g1226f6d8fa-goog |
| |