// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022 MediaTek Inc.
 * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
 */

#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"
#include "mtk-mdp3-m2m.h"
#include "mtk-img-ipi.h"

#define MDP_PATH_MAX_COMPS	IMG_MAX_COMPONENTS

struct mdp_path {
	struct mdp_dev		*mdp_dev;
	struct mdp_comp_ctx	comps[MDP_PATH_MAX_COMPS];
	u32			num_comps;
	const struct img_config	*config;
	const struct img_ipi_frameparam *param;
	const struct v4l2_rect	*composes[IMG_MAX_HW_OUTPUTS];
	struct v4l2_rect	bounds[IMG_MAX_HW_OUTPUTS];
};

#define has_op(ctx, op) \
	((ctx)->comp->ops && (ctx)->comp->ops->op)
 #define call_op(ctx, op, ...) \
	(has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)

static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 count)
{
	u32 num = 0;
	bool dis_output = false;
	bool dis_tile = false;

	if (CFG_CHECK(MT8183, p_id)) {
		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 struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev,
				     const struct mdp_pipe_info *p)
{
	return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id];
}

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;
	}
}

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:
		pipe_id = MDP_PIPE_RDMA0;
		break;
	case MDP_COMP_ISP_IMGI:
		pipe_id = MDP_PIPE_IMGI;
		break;
	case MDP_COMP_WPEI:
		pipe_id = MDP_PIPE_WPEI;
		break;
	case MDP_COMP_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:
		/* 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);
	}

	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_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_SOF_IDX_SINGLE_MODE);

	return 0;
}

static int mdp_path_subfrm_run(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;
	struct device *dev = &path->mdp_dev->pdev->dev;
	struct mtk_mutex *mutex;
	int index;
	u32 num_comp = 0;
	s32 event;
	s32 inner_id = MDP_COMP_NONE;

	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;
		event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
		if (event != MDP_GCE_NO_EVENT)
			MM_REG_CLEAR(cmd, event);
	}

	/* Enable the mutex */
	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;
		event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
		if (event != MDP_GCE_NO_EVENT)
			MM_REG_WAIT(cmd, event);
	}

	return 0;
}

static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
{
	const int p_id = mdp->mdp_data->mdp_plat_id;
	void *param = NULL;
	int index, ret;
	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);

	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)
			return ret;
	}

	return 0;
}

static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
				  struct mdp_path *path, u32 count)
{
	const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
	const struct img_mmsys_ctrl *ctrl = NULL;
	const struct img_mux *set;
	struct mdp_comp_ctx *ctx;
	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, &pipe, count);
	if (ret)
		return ret;
	/* Enable mux settings */
	for (index = 0; index < ctrl->num_sets; index++) {
		set = &ctrl->sets[index];
		cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
				    set->value, 0xFFFFFFFF);
	}
	/* 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;
		ret = call_op(ctx, config_subfrm, cmd, count);
		if (ret)
			return ret;
	}
	/* Run components */
	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;
		ret = call_op(ctx, wait_comp_event, cmd);
		if (ret)
			return ret;
	}
	/* 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)
			return ret;
	}
	/* Disable mux settings */
	for (index = 0; index < ctrl->num_sets; index++) {
		set = &ctrl->sets[index];
		cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
				    0, 0xFFFFFFFF);
	}

	return 0;
}

static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
			   struct mdp_path *path)
{
	const int p_id = mdp->mdp_data->mdp_plat_id;
	struct mdp_comp_ctx *ctx;
	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)
			return ret;
	}
	/* Config frame mode */
	for (index = 0; index < num_comp; index++) {
		const struct v4l2_rect *compose;
		u32 out = 0;

		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);
		if (ret)
			return ret;
	}

	/* Config path sub-frames */
	for (count = 0; count < num_sub; count++) {
		ret = mdp_path_config_subfrm(cmd, path, count);
		if (ret)
			return ret;
	}
	/* 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)
			return ret;
	}
	return 0;
}

static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
			       size_t size)
{
	struct device *dev;
	dma_addr_t dma_addr;

	pkt->va_base = kzalloc(size, GFP_KERNEL);
	if (!pkt->va_base)
		return -ENOMEM;

	pkt->buf_size = size;
	pkt->cl = (void *)client;

	dev = client->chan->mbox->dev;
	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
				  DMA_TO_DEVICE);
	if (dma_mapping_error(dev, dma_addr)) {
		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
		kfree(pkt->va_base);
		return -ENOMEM;
	}

	pkt->pa_base = dma_addr;

	return 0;
}

static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
{
	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;

	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
			 DMA_TO_DEVICE);
	kfree(pkt->va_base);
	pkt->va_base = NULL;
}

static void mdp_auto_release_work(struct work_struct *work)
{
	struct mdp_cmdq_cmd *cmd;
	struct mdp_dev *mdp;
	struct mtk_mutex *mutex;
	enum mdp_pipe_id pipe_id;

	cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work);
	mdp = cmd->mdp;

	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);

	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);
	cmd->comps = NULL;
	kfree(cmd);
	cmd = NULL;
}

static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
{
	struct mdp_cmdq_cmd *cmd;
	struct cmdq_cb_data *data;
	struct mdp_dev *mdp;
	struct device *dev;
	enum mdp_pipe_id pipe_id;

	if (!mssg) {
		pr_info("%s:no callback data\n", __func__);
		return;
	}

	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;

	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__);
		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);

		if (atomic_dec_and_test(&mdp->job_count))
			wake_up(&mdp->callback_wq);

		mdp_cmdq_pkt_destroy(&cmd->pkt);
		kfree(cmd->comps);
		cmd->comps = NULL;
		kfree(cmd);
		cmd = NULL;
	}
}

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;
	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_uninit;
	}

	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;
	}
	comps = kcalloc(num_comp, sizeof(*comps), GFP_KERNEL);
	if (!comps) {
		ret = -ENOMEM;
		goto err_destroy_pkt;
	}

	path = kzalloc(sizeof(*path), GFP_KERNEL);
	if (!path) {
		ret = -ENOMEM;
		goto err_free_comps;
	}

	path->mdp_dev = mdp;
	path->config = config;
	path->param = param->param;
	for (i = 0; i < param->param->num_outputs; i++) {
		path->bounds[i].left = 0;
		path->bounds[i].top = 0;
		path->bounds[i].width =
			param->param->outputs[i].buffer.format.width;
		path->bounds[i].height =
			param->param->outputs[i].buffer.format.height;
		path->composes[i] = param->composes[i] ?
			param->composes[i] : &path->bounds[i];
	}
	ret = mdp_path_ctx_init(mdp, path);
	if (ret) {
		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 %d\n", pp_idx);
		goto err_free_path;
	}
	cmdq_pkt_finalize(&cmd->pkt);

	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[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;
	cmd->comps = comps;
	cmd->num_comps = num_comp;
	cmd->mdp_ctx = param->mdp_ctx;

	kfree(path);
	return cmd;

err_free_path:
	if (mutex)
		mtk_mutex_unprepare(mutex);
	kfree(path);
err_free_comps:
	kfree(comps);
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_set(&mdp->job_count, 0);

	return ret;
}
EXPORT_SYMBOL_GPL(mdp_cmdq_send);
