diff options
Diffstat (limited to 'drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c')
-rw-r--r-- | drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 440 |
1 files changed, 344 insertions, 96 deletions
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 6adac857a4..1d64bac34b 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -6,6 +6,7 @@ #include <linux/mailbox_controller.h> #include <linux/platform_device.h> +#include "mtk-mdp3-cfg.h" #include "mtk-mdp3-cmdq.h" #include "mtk-mdp3-comp.h" #include "mtk-mdp3-core.h" @@ -39,85 +40,192 @@ static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 num = CFG_COMP(MT8183, param, num_subfrms); dis_output = CFG_COMP(MT8183, param, frame.output_disable); dis_tile = CFG_COMP(MT8183, param, frame.output_disable); + } else if (CFG_CHECK(MT8195, p_id)) { + num = CFG_COMP(MT8195, param, num_subfrms); + dis_output = CFG_COMP(MT8195, param, frame.output_disable); + dis_tile = CFG_COMP(MT8195, param, frame.output_disable); } return (count < num) ? (dis_output || dis_tile) : true; } -static int mdp_path_subfrm_require(const struct mdp_path *path, - struct mdp_cmdq_cmd *cmd, - s32 *mutex_id, u32 count) +static struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev, + const struct mdp_pipe_info *p) { - const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; - const struct mdp_comp_ctx *ctx; - const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data; - struct device *dev = &path->mdp_dev->pdev->dev; - struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex; - int id, index; - u32 num_comp = 0; + return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id]; +} - if (CFG_CHECK(MT8183, p_id)) - num_comp = CFG_GET(MT8183, path->config, num_components); +static u8 __get_pp_num(enum mdp_stream_type type) +{ + switch (type) { + case MDP_STREAM_TYPE_DUAL_BITBLT: + return MDP_PP_USED_2; + default: + return MDP_PP_USED_1; + } +} - /* Decide which mutex to use based on the current pipeline */ - switch (path->comps[0].comp->public_id) { +static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev, + enum mtk_mdp_comp_id id) +{ + enum mdp_pipe_id pipe_id; + + switch (id) { case MDP_COMP_RDMA0: - index = MDP_PIPE_RDMA0; + pipe_id = MDP_PIPE_RDMA0; break; case MDP_COMP_ISP_IMGI: - index = MDP_PIPE_IMGI; + pipe_id = MDP_PIPE_IMGI; break; case MDP_COMP_WPEI: - index = MDP_PIPE_WPEI; + pipe_id = MDP_PIPE_WPEI; break; case MDP_COMP_WPEI2: - index = MDP_PIPE_WPEI2; + pipe_id = MDP_PIPE_WPEI2; + break; + case MDP_COMP_RDMA1: + pipe_id = MDP_PIPE_RDMA1; + break; + case MDP_COMP_RDMA2: + pipe_id = MDP_PIPE_RDMA2; + break; + case MDP_COMP_RDMA3: + pipe_id = MDP_PIPE_RDMA3; break; default: - dev_err(dev, "Unknown pipeline and no mutex is assigned"); - return -EINVAL; + /* Avoid exceptions when operating MUTEX */ + pipe_id = MDP_PIPE_RDMA0; + dev_err(&mdp_dev->pdev->dev, "Unknown pipeline id %d", id); + break; + } + + return pipe_id; +} + +static struct img_config *__get_config_offset(struct mdp_dev *mdp, + struct mdp_cmdq_param *param, + u8 pp_idx) +{ + const int p_id = mdp->mdp_data->mdp_plat_id; + struct device *dev = &mdp->pdev->dev; + void *cfg_c, *cfg_n; + long bound = mdp->vpu.config_size; + + if (pp_idx >= mdp->mdp_data->pp_used) + goto err_param; + + if (CFG_CHECK(MT8183, p_id)) + cfg_c = CFG_OFST(MT8183, param->config, pp_idx); + else if (CFG_CHECK(MT8195, p_id)) + cfg_c = CFG_OFST(MT8195, param->config, pp_idx); + else + goto err_param; + + if (CFG_CHECK(MT8183, p_id)) + cfg_n = CFG_OFST(MT8183, param->config, pp_idx + 1); + else if (CFG_CHECK(MT8195, p_id)) + cfg_n = CFG_OFST(MT8195, param->config, pp_idx + 1); + else + goto err_param; + + if ((long)cfg_n - (long)mdp->vpu.config > bound) { + dev_err(dev, "config offset %ld OOB %ld\n", (long)cfg_n, bound); + cfg_c = ERR_PTR(-EFAULT); } - *mutex_id = data->pipe_info[index].mutex_id; + + return (struct img_config *)cfg_c; + +err_param: + cfg_c = ERR_PTR(-EINVAL); + return (struct img_config *)cfg_c; +} + +static int mdp_path_subfrm_require(const struct mdp_path *path, + struct mdp_cmdq_cmd *cmd, + struct mdp_pipe_info *p, u32 count) +{ + const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; + const struct mdp_comp_ctx *ctx; + const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data; + struct mtk_mutex *mutex; + int id, index; + u32 num_comp = 0; + + if (CFG_CHECK(MT8183, p_id)) + num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); + + /* Decide which mutex to use based on the current pipeline */ + index = __get_pipe(path->mdp_dev, path->comps[0].comp->public_id); + memcpy(p, &data->pipe_info[index], sizeof(struct mdp_pipe_info)); + mutex = __get_mutex(path->mdp_dev, p); /* Set mutex mod */ for (index = 0; index < num_comp; index++) { + s32 inner_id = MDP_COMP_NONE; + const u32 *mutex_idx; + const struct mdp_comp_blend *b; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; + ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; + + mutex_idx = data->mdp_mutex_table_idx; id = ctx->comp->public_id; - mtk_mutex_write_mod(mutex[*mutex_id], - data->mdp_mutex_table_idx[id], false); + mtk_mutex_write_mod(mutex, mutex_idx[id], false); + + b = &data->comp_data[id].blend; + if (b && b->aid_mod) + mtk_mutex_write_mod(mutex, mutex_idx[b->b_id], false); } - mtk_mutex_write_sof(mutex[*mutex_id], - MUTEX_SOF_IDX_SINGLE_MODE); + mtk_mutex_write_sof(mutex, MUTEX_SOF_IDX_SINGLE_MODE); return 0; } static int mdp_path_subfrm_run(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, - s32 *mutex_id, u32 count) + struct mdp_pipe_info *p, u32 count) { const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; const struct mdp_comp_ctx *ctx; struct device *dev = &path->mdp_dev->pdev->dev; - struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex; + struct mtk_mutex *mutex; int index; u32 num_comp = 0; s32 event; + s32 inner_id = MDP_COMP_NONE; - if (-1 == *mutex_id) { + if (-1 == p->mutex_id) { dev_err(dev, "Incorrect mutex id"); return -EINVAL; } if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); /* Wait WROT SRAM shared to DISP RDMA */ /* Clear SOF event for each engine */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -127,10 +235,18 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, } /* Enable the mutex */ - mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt); + mutex = __get_mutex(path->mdp_dev, p); + mtk_mutex_enable_by_cmdq(mutex, (void *)&cmd->pkt); /* Wait SOF events and clear mutex modules (optional) */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -151,13 +267,26 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path) if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (num_comp < 1) return -EINVAL; for (index = 0; index < num_comp; index++) { + s32 inner_id = MDP_COMP_NONE; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; if (CFG_CHECK(MT8183, p_id)) param = (void *)CFG_ADDR(MT8183, path->config, components[index]); + else if (CFG_CHECK(MT8195, p_id)) + param = (void *)CFG_ADDR(MT8195, path->config, components[index]); ret = mdp_comp_ctx_config(mdp, &path->comps[index], param, path->param); if (ret) @@ -174,18 +303,23 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, const struct img_mmsys_ctrl *ctrl = NULL; const struct img_mux *set; struct mdp_comp_ctx *ctx; - s32 mutex_id; + struct mdp_pipe_info pipe; int index, ret; u32 num_comp = 0; + s32 inner_id = MDP_COMP_NONE; if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (CFG_CHECK(MT8183, p_id)) ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]); + else if (CFG_CHECK(MT8195, p_id)) + ctrl = CFG_ADDR(MT8195, path->config, ctrls[count]); /* Acquire components */ - ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count); + ret = mdp_path_subfrm_require(path, cmd, &pipe, count); if (ret) return ret; /* Enable mux settings */ @@ -196,6 +330,13 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, } /* Config sub-frame information */ for (index = (num_comp - 1); index >= 0; index--) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -204,11 +345,18 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, return ret; } /* Run components */ - ret = mdp_path_subfrm_run(path, cmd, &mutex_id, count); + ret = mdp_path_subfrm_run(path, cmd, &pipe, count); if (ret) return ret; /* Wait components done */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -218,6 +366,13 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, } /* Advance to the next sub-frame */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, advance_subfrm, cmd, count); if (ret) @@ -241,16 +396,28 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, int index, count, ret; u32 num_comp = 0; u32 num_sub = 0; + s32 inner_id = MDP_COMP_NONE; if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (CFG_CHECK(MT8183, p_id)) num_sub = CFG_GET(MT8183, path->config, num_subfrms); + else if (CFG_CHECK(MT8195, p_id)) + num_sub = CFG_GET(MT8195, path->config, num_subfrms); /* Config path frame */ /* Reset components */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, init_comp, cmd); if (ret) @@ -263,7 +430,17 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, ctx = &path->comps[index]; if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; + + if (CFG_CHECK(MT8183, p_id)) out = CFG_COMP(MT8183, ctx->param, outputs[0]); + else if (CFG_CHECK(MT8195, p_id)) + out = CFG_COMP(MT8195, ctx->param, outputs[0]); compose = path->composes[out]; ret = call_op(ctx, config_frame, cmd, compose); @@ -279,6 +456,13 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, } /* Post processing information */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, post_process, cmd); if (ret) @@ -328,18 +512,31 @@ static void mdp_auto_release_work(struct work_struct *work) { struct mdp_cmdq_cmd *cmd; struct mdp_dev *mdp; - int id; + struct mtk_mutex *mutex; + enum mdp_pipe_id pipe_id; cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work); mdp = cmd->mdp; - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[id]); + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); + mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - atomic_dec(&mdp->job_count); - wake_up(&mdp->callback_wq); + if (atomic_dec_and_test(&mdp->job_count)) { + if (cmd->mdp_ctx) + mdp_m2m_job_finish(cmd->mdp_ctx); + + if (cmd->user_cmdq_cb) { + struct cmdq_cb_data user_cb_data; + + user_cb_data.sta = cmd->data->sta; + user_cb_data.pkt = cmd->data->pkt; + cmd->user_cmdq_cb(user_cb_data); + } + wake_up(&mdp->callback_wq); + } mdp_cmdq_pkt_destroy(&cmd->pkt); kfree(cmd->comps); @@ -354,7 +551,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) struct cmdq_cb_data *data; struct mdp_dev *mdp; struct device *dev; - int id; + enum mdp_pipe_id pipe_id; if (!mssg) { pr_info("%s:no callback data\n", __func__); @@ -363,30 +560,23 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) data = (struct cmdq_cb_data *)mssg; cmd = container_of(data->pkt, struct mdp_cmdq_cmd, pkt); + cmd->data = data; mdp = cmd->mdp; dev = &mdp->pdev->dev; - if (cmd->mdp_ctx) - mdp_m2m_job_finish(cmd->mdp_ctx); - - if (cmd->user_cmdq_cb) { - struct cmdq_cb_data user_cb_data; - - user_cb_data.sta = data->sta; - user_cb_data.pkt = data->pkt; - cmd->user_cmdq_cb(user_cb_data); - } - INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work); if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) { + struct mtk_mutex *mutex; + dev_err(dev, "%s:queue_work fail!\n", __func__); - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[id]); + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); + mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - atomic_dec(&mdp->job_count); - wake_up(&mdp->callback_wq); + if (atomic_dec_and_test(&mdp->job_count)) + wake_up(&mdp->callback_wq); mdp_cmdq_pkt_destroy(&cmd->pkt); kfree(cmd->comps); @@ -396,34 +586,48 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) } } -int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) +static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp, + struct mdp_cmdq_param *param, + u8 pp_idx) { struct mdp_path *path = NULL; struct mdp_cmdq_cmd *cmd = NULL; struct mdp_comp *comps = NULL; struct device *dev = &mdp->pdev->dev; const int p_id = mdp->mdp_data->mdp_plat_id; - int i, ret; - u32 num_comp = 0; - - atomic_inc(&mdp->job_count); - if (atomic_read(&mdp->suspended)) { - atomic_dec(&mdp->job_count); - return -ECANCELED; + struct img_config *config; + struct mtk_mutex *mutex = NULL; + enum mdp_pipe_id pipe_id; + int i, ret = -ECANCELED; + u32 num_comp; + + config = __get_config_offset(mdp, param, pp_idx); + if (IS_ERR(config)) { + ret = PTR_ERR(config); + goto err_uninit; } + if (CFG_CHECK(MT8183, p_id)) + num_comp = CFG_GET(MT8183, config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, config, num_components); + else + goto err_uninit; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) { ret = -ENOMEM; - goto err_cancel_job; + goto err_uninit; } - ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K); + ret = mdp_cmdq_pkt_create(mdp->cmdq_clt[pp_idx], &cmd->pkt, SZ_16K); if (ret) goto err_free_cmd; if (CFG_CHECK(MT8183, p_id)) { num_comp = CFG_GET(MT8183, param->config, num_components); + } else if (CFG_CHECK(MT8195, p_id)) { + num_comp = CFG_GET(MT8195, param->config, num_components); } else { ret = -EINVAL; goto err_destroy_pkt; @@ -440,15 +644,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_comps; } - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - ret = mtk_mutex_prepare(mdp->mdp_mutex[i]); - if (ret) { - dev_err(dev, "Fail to enable mutex clk\n"); - goto err_free_path; - } - path->mdp_dev = mdp; - path->config = param->config; + path->config = config; path->param = param->param; for (i = 0; i < param->param->num_outputs; i++) { path->bounds[i].left = 0; @@ -462,22 +659,40 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) } ret = mdp_path_ctx_init(mdp, path); if (ret) { - dev_err(dev, "mdp_path_ctx_init error\n"); + dev_err(dev, "mdp_path_ctx_init error %d\n", pp_idx); + goto err_free_path; + } + + pipe_id = __get_pipe(mdp, path->comps[0].comp->public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); + ret = mtk_mutex_prepare(mutex); + if (ret) { + dev_err(dev, "Fail to enable mutex %d clk\n", pp_idx); goto err_free_path; } ret = mdp_path_config(mdp, cmd, path); if (ret) { - dev_err(dev, "mdp_path_config error\n"); + dev_err(dev, "mdp_path_config error %d\n", pp_idx); goto err_free_path; } cmdq_pkt_finalize(&cmd->pkt); - for (i = 0; i < num_comp; i++) + for (i = 0; i < num_comp; i++) { + s32 inner_id = MDP_COMP_NONE; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[i].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[i].type); + + if (mdp_cfg_comp_is_dummy(mdp, inner_id)) + continue; memcpy(&comps[i], path->comps[i].comp, sizeof(struct mdp_comp)); + } - mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback; + mdp->cmdq_clt[pp_idx]->client.rx_callback = mdp_handle_cmdq_callback; cmd->mdp = mdp; cmd->user_cmdq_cb = param->cmdq_cb; cmd->user_cb_data = param->cb_data; @@ -485,29 +700,12 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) cmd->num_comps = num_comp; cmd->mdp_ctx = param->mdp_ctx; - ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - if (ret) - goto err_free_path; - - dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev, - cmd->pkt.pa_base, cmd->pkt.cmd_buf_size, - DMA_TO_DEVICE); - ret = mbox_send_message(mdp->cmdq_clt->chan, &cmd->pkt); - if (ret < 0) { - dev_err(dev, "mbox send message fail %d!\n", ret); - goto err_clock_off; - } - mbox_client_txdone(mdp->cmdq_clt->chan, 0); - kfree(path); - return 0; + return cmd; -err_clock_off: - mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, - cmd->num_comps); err_free_path: - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[i]); + if (mutex) + mtk_mutex_unprepare(mutex); kfree(path); err_free_comps: kfree(comps); @@ -515,8 +713,58 @@ err_destroy_pkt: mdp_cmdq_pkt_destroy(&cmd->pkt); err_free_cmd: kfree(cmd); +err_uninit: + return ERR_PTR(ret); +} + +int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) +{ + struct mdp_cmdq_cmd *cmd[MDP_PP_MAX] = {NULL}; + struct device *dev = &mdp->pdev->dev; + int i, ret; + u8 pp_used = __get_pp_num(param->param->type); + + atomic_set(&mdp->job_count, pp_used); + if (atomic_read(&mdp->suspended)) { + atomic_set(&mdp->job_count, 0); + return -ECANCELED; + } + + for (i = 0; i < pp_used; i++) { + cmd[i] = mdp_cmdq_prepare(mdp, param, i); + if (IS_ERR_OR_NULL(cmd[i])) { + ret = PTR_ERR(cmd[i]); + goto err_cancel_job; + } + } + + for (i = 0; i < pp_used; i++) { + ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd[i]->comps, cmd[i]->num_comps); + if (ret) + goto err_clock_off; + } + + for (i = 0; i < pp_used; i++) { + dma_sync_single_for_device(mdp->cmdq_clt[i]->chan->mbox->dev, + cmd[i]->pkt.pa_base, cmd[i]->pkt.cmd_buf_size, + DMA_TO_DEVICE); + + ret = mbox_send_message(mdp->cmdq_clt[i]->chan, &cmd[i]->pkt); + if (ret < 0) { + dev_err(dev, "mbox send message fail %d!\n", ret); + i = pp_used; + goto err_clock_off; + } + mbox_client_txdone(mdp->cmdq_clt[i]->chan, 0); + } + return 0; + +err_clock_off: + while (--i >= 0) + mdp_comp_clocks_off(&mdp->pdev->dev, cmd[i]->comps, + cmd[i]->num_comps); err_cancel_job: - atomic_dec(&mdp->job_count); + atomic_set(&mdp->job_count, 0); return ret; } |