summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c')
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c440
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 6adac857a..1d64bac34 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;
}