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

#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "mtk-mdp3-cmdq.h"
#include "mtk-mdp3-comp.h"
#include "mtk-mdp3-core.h"
#include "mtk-mdp3-debug.h"
#include "mtk-mdp3-m2m.h"

#include "mdp-platform.h"
#include "mmsys_mutex.h"

#define DISP_MUTEX_MDP_FIRST	(5)
#define DISP_MUTEX_MDP_COUNT	(5)

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

struct mdp_path_subfrm {
	s32	mutex_id;
	u32	mutex_mod;
	s32	sofs[MDP_PATH_MAX_COMPS];
	u32	num_sofs;
};

static bool is_output_disable(const struct img_compparam *param, u32 count)
{
	return (count < param->num_subfrms) ?
		(param->frame.output_disable ||
		param->subfrms[count].tile_disable) :
		true;
}

static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
				   const struct mdp_path *path,
				   struct mdp_cmd *cmd, u32 count)
{
	const struct img_config *config = path->config;
	const struct mdp_comp_ctx *ctx;
	phys_addr_t mm_mutex = path->mdp_dev->mm_mutex.reg_base;
	s32 mutex_id = -1;
	u32 mutex_sof = 0;
	int index;
	u16 subsys_id = path->mdp_dev->mm_mutex.subsys_id;

	/* Default value */
	memset(subfrm, 0, sizeof(*subfrm));

	for (index = 0; index < config->num_components; index++) {
		ctx = &path->comps[index];
		if (is_output_disable(ctx->param, count))
			continue;

		switch (ctx->comp->id) {
        /**********************************************
             * Name            MSB LSB
             * MDP_MUTEX_MOD0   31   0
             * MDP_MUTEX_MOD1    1   0
             *
             * Specifies which modules are in this mutex.
             * Every bit denotes a module. Bit definition:
             *  0 mdp_rdma0
             *  1 mdp_rdma1
             *  2 mdp_aal0
             *  3 mdp_aal1
             *  4 mdp_hdr0
             *  5 mdp_hdr1
             *  6 mdp_rsz0
             *  7 mdp_rsz1
             *  8 mdp_wrot0
             *  9 mdp_wrot1
             * 10 mdp_tdshp0
             * 11 mdp_tdshp1
             * 12 isp_relay0
             * 13 isp_relay1
             * 14 mdp_color0
             * 15 mdp_color1
             **********************************************/
        case MDP_IMGI:
			mutex_id = 0;
			break;
		case MDP_WPEI:
			mutex_id = 1;
			break;
	    case MDP_WPEI2:
			mutex_id = 2; 
			break;
		case MDP_RDMA0:
		    mutex_id = 3;
			subfrm->mutex_mod |= 1 << 0;
			subfrm->sofs[subfrm->num_sofs++] = MDP_RDMA0;
			break;
		case MDP_RDMA1:
		    mutex_id = 4;
			subfrm->mutex_mod |= 1 << 1;
			subfrm->sofs[subfrm->num_sofs++] = MDP_RDMA1;
			break;
		case MDP_AAL0:
			subfrm->mutex_mod |= 1 << 2;
			break;
		case MDP_AAL1:
			subfrm->mutex_mod |= 1 << 3;
			break;
		case MDP_HDR0:
			subfrm->mutex_mod |= 1 << 4;
			break;
		case MDP_HDR1:
			subfrm->mutex_mod |= 1 << 5;
			break;
		case MDP_SCL0:
			subfrm->mutex_mod |= 1 << 6;
			subfrm->sofs[subfrm->num_sofs++] = MDP_SCL0;
			break;
		case MDP_SCL1:
			subfrm->mutex_mod |= 1 << 7;
			subfrm->sofs[subfrm->num_sofs++] = MDP_SCL1;
			break;
		case MDP_WROT0:
			subfrm->mutex_mod |= 1 << 8;
			subfrm->sofs[subfrm->num_sofs++] = MDP_WROT0;
			break;
		case MDP_WROT1:
			subfrm->mutex_mod |= 1 << 9;
			subfrm->sofs[subfrm->num_sofs++] = MDP_WROT1;
			break;
		case MDP_TDSHP0:
			subfrm->mutex_mod |= 1 << 10;
			subfrm->sofs[subfrm->num_sofs++] = MDP_TDSHP0;
			break;
		case MDP_TDSHP1:
			subfrm->mutex_mod |= 1 << 11;
			subfrm->sofs[subfrm->num_sofs++] = MDP_TDSHP1;
			break;
		case MDP_CAMIN:
			subfrm->mutex_mod |= 1 << 12;
			break;
		case MDP_CAMIN2:
			subfrm->mutex_mod |= 1 << 13;
			break;
		case MDP_COLOR0:
			subfrm->mutex_mod |= 1 << 14;
			break;
		case MDP_COLOR1:
			subfrm->mutex_mod |= 1 << 15;
			break;
		default:
			break;
		}
	}

	subfrm->mutex_id = mutex_id;
	if (-1 == mutex_id) {
		mdp_err("No mutex assigned");
		return -EINVAL;
	}

	if (subfrm->mutex_mod) {
		/* Set mutex modules */
		MM_REG_WRITE_S(cmd, subsys_id, mm_mutex, MM_MUTEX_MOD,
			     subfrm->mutex_mod, 0x07FFFFFF);
		MM_REG_WRITE_S(cmd, subsys_id, mm_mutex, MM_MUTEX_SOF,
			     mutex_sof, 0x00000007);
	}
	return 0;
}

static int mdp_path_subfrm_run(const struct mdp_path_subfrm *subfrm,
			       const struct mdp_path *path,
			       struct mdp_cmd *cmd)
{
	phys_addr_t mm_mutex = path->mdp_dev->mm_mutex.reg_base;
	s32 mutex_id = subfrm->mutex_id;
	u16 subsys_id = path->mdp_dev->mm_mutex.subsys_id;

	if (-1 == mutex_id) {
		mdp_err("Incorrect mutex id");
		return -EINVAL;
	}

	if (subfrm->mutex_mod) {
		int index;

		/* Wait WROT SRAM shared to DISP RDMA */
		/* Clear SOF event for each engine */
		for (index = 0; index < subfrm->num_sofs; index++) {
			switch (subfrm->sofs[index]) {
			case MDP_RDMA0:
				MM_REG_CLEAR(cmd, RDMA0_SOF);
				break;
			case MDP_RDMA1:
				MM_REG_CLEAR(cmd, RDMA1_SOF);
				break;
			case MDP_WROT0:
				MM_REG_CLEAR(cmd, WROT0_SOF);
				break;
			case MDP_WROT1:
				MM_REG_CLEAR(cmd, WROT1_SOF);
				break;
			default:
				break;
			}
		}

		/* Enable the mutex */
		MM_REG_WRITE_S(cmd, subsys_id, mm_mutex, MM_MUTEX_EN, 0x1,
			     0x00000001);

		/* Wait SOF events and clear mutex modules (optional) */
		for (index = 0; index < subfrm->num_sofs; index++) {
			switch (subfrm->sofs[index]) {
			case MDP_RDMA0:
				MM_REG_WAIT(cmd, RDMA0_SOF);
				break;
			case MDP_RDMA1:
				MM_REG_WAIT(cmd, RDMA1_SOF);
				break;
			case MDP_WROT0:
				MM_REG_WAIT(cmd, WROT0_SOF);
				break;
			case MDP_WROT1:
				MM_REG_WAIT(cmd, WROT1_SOF);
				break;
			default:
				break;
			}
		}
	}
	return 0;
}

static int mdp_path_config_subfrm(struct mdp_cmd *cmd, struct mdp_path *path,
				  u32 count)
{
	struct mdp_path_subfrm subfrm;
	const struct img_config *config = path->config;
	const struct img_mmsys_ctrl *ctrl = &config->ctrls[count];
	const struct img_mux *set;
	struct mdp_comp_ctx *ctx;
	phys_addr_t mmsys = path->mdp_dev->mmsys.reg_base;
	int index, ret;
	u16 subsys_id = path->mdp_dev->mmsys.subsys_id;

	/* Acquire components */
	ret = mdp_path_subfrm_require(&subfrm, path, cmd, count);
	if (ret)
		return ret;
	/* Enable mux settings */
	for (index = 0; index < ctrl->num_sets; index++) {
		set = &ctrl->sets[index];
		MM_REG_WRITE_S(cmd, subsys_id, mmsys, set->reg, set->value,
				  0xFFFFFFFF);
	}
	/* Config sub-frame information */
	for (index = (config->num_components - 1); index >= 0; index--) {
		ctx = &path->comps[index];
		if (is_output_disable(ctx->param, count))
			continue;
		ret = call_op(ctx, config_subfrm, cmd, count);
		if (ret)
			return ret;
	}
	/* Run components */
	ret = mdp_path_subfrm_run(&subfrm, path, cmd);
	if (ret)
		return ret;
	/* Wait components done */
	for (index = 0; index < config->num_components; index++) {
		ctx = &path->comps[index];
		if (is_output_disable(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 < config->num_components; index++) {
		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];
		MM_REG_WRITE_S(cmd, subsys_id, mmsys, set->reg, 0,
				  0xFFFFFFFF);
	}
	return 0;
}

static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
{
	const struct img_config *config = path->config;
	int index, ret;

	if (config->num_components < 1)
	    return -EINVAL;

	for (index = 0; index < config->num_components; index++) {
		ret = mdp_comp_ctx_init(mdp, &path->comps[index],
					&config->components[index],
					path->param);
		if (ret)
			return ret;
	}

	return 0;
}

static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmd *cmd,
			   struct mdp_path *path)
{
	const struct img_config *config = path->config;
	struct mdp_comp_ctx *ctx;
	int index, count, ret;

	/* Config path frame */
	/* Reset components */
	for (index = 0; index < config->num_components; index++) {
		ctx = &path->comps[index];
		ret = call_op(ctx, init_comp, cmd);
		if (ret)
			return ret;
	}
	/* Config frame mode */
	for (index = 0; index < config->num_components; index++) {
		const struct v4l2_rect *compose =
			path->composes[ctx->param->outputs[0]];

		ctx = &path->comps[index];
		ret = call_op(ctx, config_frame, cmd, compose);
		if (ret)
			return ret;
	}

	/* Config path sub-frames */
	for (count = 0; count < config->num_subfrms; count++) {
		ret = mdp_path_config_subfrm(cmd, path, count);
		if (ret)
			return ret;
	}
	/* Post processing information */
	for (index = 0; index < config->num_components; index++) {
		ctx = &path->comps[index];
		ret = call_op(ctx, post_process, cmd);
		if (ret)
			return ret;
	}
	return 0;
}

static void mdp_auto_release_work(struct work_struct *work)
{
	struct mdp_cmdq_cb_param *cb_param;
	struct mdp_dev *mdp;

	cb_param = container_of(work, struct mdp_cmdq_cb_param,
				auto_release_work);
	mdp = cb_param->mdp;

	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
			    cb_param->num_comps);
	mdp_comp_clock_off(&mdp->pdev->dev, &mdp->mm_mutex);
	pm_runtime_put_sync(&mdp->pdev->dev);

	kfree(cb_param->comps);
	kfree(cb_param);

	atomic_dec(&mdp->job_count);
	wake_up(&mdp->callback_wq);
}

static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
{
	struct mdp_cmdq_cb_param *cb_param;
	struct mdp_dev *mdp;

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

	cb_param = (struct mdp_cmdq_cb_param *)data.data;
	mdp = cb_param->mdp;

	if (cb_param->mdp_ctx)
		mdp_m2m_job_finish(cb_param->mdp_ctx);
#ifdef MDP_DEBUG
	if (data.sta == CMDQ_CB_ERROR) {
		struct mdp_func_struct *p_func = mdp_get_func();

		p_func->mdp_dump_mmsys_config();
		mdp_dump_info(~0, 1);
	}
#endif

	if (cb_param->user_cmdq_cb) {
		struct cmdq_cb_data user_cb_data;

		user_cb_data.sta = data.sta;
		user_cb_data.data = cb_param->user_cb_data;
		cb_param->user_cmdq_cb(user_cb_data);
	}

	cmdq_pkt_destroy(cb_param->pkt);
	INIT_WORK(&cb_param->auto_release_work, mdp_auto_release_work);
	if (!queue_work(mdp->clock_wq, &cb_param->auto_release_work)) {
		mdp_err("%s:queue_work fail!\n", __func__);
		mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
				    cb_param->num_comps);
		mdp_comp_clock_off(&mdp->pdev->dev, &mdp->mm_mutex);
		pm_runtime_put_sync(&mdp->pdev->dev);

		kfree(cb_param->comps);
		kfree(cb_param);

		atomic_dec(&mdp->job_count);
		wake_up(&mdp->callback_wq);
	}
}

int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
{
	struct mdp_cmd cmd;
	struct mdp_path path;
	struct mdp_cmdq_cb_param *cb_param = NULL;
	struct mdp_comp *comps = NULL;
	int i, ret;

	if (atomic_read(&mdp->suspended))
		return -ECANCELED;

	atomic_inc(&mdp->job_count);

	cmd.pkt = cmdq_pkt_create(mdp->cmdq_clt, SZ_16K);
	if (IS_ERR(cmd.pkt)) {
		atomic_dec(&mdp->job_count);
		wake_up(&mdp->callback_wq);
		return PTR_ERR(cmd.pkt);
	}
	cmd.event = &mdp->event[0];

	path.mdp_dev = mdp;
	path.config = param->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) {
		pr_info("%s mdp_path_ctx_init error\n", __func__);
		goto err_destory_pkt;
	}

	ret = mdp_path_config(mdp, &cmd, &path);
	if (ret) {
		pr_info("%s mdp_path_config error\n", __func__);
		goto err_destory_pkt;
	}

	if (param->wait) {
	    pm_runtime_get_sync(&mdp->pdev->dev);
	    mdp_comp_clock_on(&mdp->pdev->dev, &mdp->mm_mutex);
		for (i = 0; i < param->config->num_components; i++)
			mdp_comp_clock_on(&mdp->pdev->dev, path.comps[i].comp);
		ret = cmdq_pkt_flush(cmd.pkt);
#ifdef MDP_DEBUG
        if (ret) {
	        struct mdp_func_struct *p_func = mdp_get_func();

	        p_func->mdp_dump_mmsys_config();
	        mdp_dump_info(~0, 1);
		}
#endif
		if (!ret) { /* error handle in mdp_m2m_worker */
			if (param->mdp_ctx)
				mdp_m2m_job_finish(param->mdp_ctx);
		}
		goto err_clock_off;
	} else {
		cb_param = kzalloc(sizeof(*cb_param), GFP_KERNEL);
		if (!cb_param) {
			ret = -ENOMEM;
			goto err_destory_pkt;
		}

		comps = kcalloc(param->config->num_components, sizeof(*comps),
				GFP_KERNEL);
		if (!comps) {
			mdp_err("%s:comps alloc fail!\n", __func__);
			ret = -ENOMEM;
			goto err_destory_pkt;
		}

		for (i = 0; i < param->config->num_components; i++)
			memcpy(&comps[i], path.comps[i].comp,
			       sizeof(struct mdp_comp));
		cb_param->mdp = mdp;
		cb_param->user_cmdq_cb = param->cmdq_cb;
		cb_param->user_cb_data = param->cb_data;
		cb_param->pkt = cmd.pkt;
		cb_param->comps = comps;
		cb_param->num_comps = param->config->num_components;
		cb_param->mdp_ctx = param->mdp_ctx;

		pm_runtime_get_sync(&mdp->pdev->dev);
		mdp_comp_clock_on(&mdp->pdev->dev, &mdp->mm_mutex);
		mdp_comp_clocks_on(&mdp->pdev->dev, cb_param->comps,
				   cb_param->num_comps);

		ret = cmdq_pkt_flush_async(cmd.pkt,
					   mdp_handle_cmdq_callback,
					   (void *)cb_param);
		if (ret) {
			mdp_err("%s:cmdq_pkt_flush_async fail!\n", __func__);
			goto err_clock_off;
		}
	}
	return 0;

err_clock_off:
	if (param->wait) {
		for (i = 0; i < param->config->num_components; i++)
			mdp_comp_clock_off(&mdp->pdev->dev, path.comps[i].comp);
		mdp_comp_clock_off(&mdp->pdev->dev, &mdp->mm_mutex);
	} else {
		mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
					    cb_param->num_comps);
		mdp_comp_clock_off(&mdp->pdev->dev, &mdp->mm_mutex);
	}
	pm_runtime_put_sync(&mdp->pdev->dev);
err_destory_pkt:
	cmdq_pkt_destroy(cmd.pkt);
	atomic_dec(&mdp->job_count);
	if (param->wait)
		wake_up(&mdp->callback_wq);
	if (comps)
		kfree(comps);
	if (cb_param)
		kfree(cb_param);

	return ret;
}

int mdp_cmdq_sendtask(struct platform_device *pdev, struct img_config *config,
		      struct img_ipi_frameparam *param,
		      struct v4l2_rect *compose, unsigned int wait,
		      void (*cmdq_cb)(struct cmdq_cb_data data), void *cb_data)
{
	struct mdp_dev *mdp = platform_get_drvdata(pdev);
	struct mdp_cmdq_param task = {
		.config = config,
		.param = param,
		.composes[0] = compose,
		.wait = wait,
		.cmdq_cb = cmdq_cb,
		.cb_data = cb_data,
	};

	return mdp_cmdq_send(mdp, &task);
}
EXPORT_SYMBOL_GPL(mdp_cmdq_sendtask);

