/*
 * Copyright (c) 2022, Mediatek Inc. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>

#include <common/debug.h>
#include <drivers/arm/gicv3.h>
#include <lib/psci/psci.h>
#include <lib/utils.h>
#ifdef MTK_PUBEVENT_ENABLE
#include <mtk_event/mtk_pubsub_events.h>
#endif
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>

#include <dfd.h>
#include <lib/mtk_init/mtk_init.h>
#include <lib/pm/mtk_pm.h>
#include <mt_gic_v3.h>
#include <platform_def.h>

#define IS_AFFLV_PUBEVENT(_pstate) \
	((_pstate & (MT_CPUPM_PWR_DOMAIN_MCUSYS | MT_CPUPM_PWR_DOMAIN_CLUSTER)) != 0)

#ifdef MTK_PUBEVENT_ENABLE
#define MT_CPUPM_EVENT_PWR_ON(x) ({ \
	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_on, (const void *)(x)); })

#define MT_CPUPM_EVENT_PWR_OFF(x) ({ \
	PUBLISH_EVENT_ARG(mt_cpupm_publish_pwr_off, (const void *)(x)); })

#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ \
	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_on, (const void *)(x)); })

#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ \
	PUBLISH_EVENT_ARG(mt_cpupm_publish_afflv_pwr_off, (const void *)(x)); })

#else
#define MT_CPUPM_EVENT_PWR_ON(x) ({ (void)x; })
#define MT_CPUPM_EVENT_PWR_OFF(x) ({ (void)x; })
#define MT_CPUPM_EVENT_AFFLV_PWR_ON(x) ({ (void)x; })
#define MT_CPUPM_EVENT_AFFLV_PWR_OFF(x) ({ (void)x; })
#endif

/*
 * The cpu require to cluster power stattus
 * [0] : The cpu require cluster power down
 * [1] : The cpu require cluster power on
 */
#define coordinate_cluster(onoff) write_clusterpwrdn_el1(onoff)
#define coordinate_cluster_pwron() coordinate_cluster(1)
#define coordinate_cluster_pwroff() coordinate_cluster(0)

/* defaultly disable all functions */
#define MTK_CPUPM_FN_MASK_DEFAULT	(0)

struct mtk_cpu_pwr_ctrl {
	unsigned int fn_mask;
	struct mtk_cpu_pm_ops *ops;
	struct mtk_cpu_smp_ops *smp;
};

static struct mtk_cpu_pwr_ctrl mtk_cpu_pwr = {
	.fn_mask = MTK_CPUPM_FN_MASK_DEFAULT,
	.ops = NULL,
};

#define IS_CPUIDLE_FN_ENABLE(x)	((mtk_cpu_pwr.ops != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))
#define IS_CPUSMP_FN_ENABLE(x)	((mtk_cpu_pwr.smp != NULL) && ((mtk_cpu_pwr.fn_mask & x) != 0))

/* per-cpu power state */
static unsigned int armv8_2_power_state[PLATFORM_CORE_COUNT];

#define armv8_2_get_pwr_stateid(cpu) psci_get_pstate_id(armv8_2_power_state[cpu])

static unsigned int get_mediatek_pstate(unsigned int domain, unsigned int psci_state,
					struct mtk_cpupm_pwrstate *state)
{
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_CPUPM_GET_PWR_STATE)) {
		return mtk_cpu_pwr.ops->get_pstate(domain, psci_state, state);
	}

	return 0;
}

unsigned int armv8_2_get_pwr_afflv(const psci_power_state_t *state_info)
{
	int i;

	for (i = (int)PLAT_MAX_PWR_LVL; i >= (int)PSCI_CPU_PWR_LVL; i--) {
		if (is_local_state_run(state_info->pwr_domain_state[i]) == 0) {
			return (unsigned int) i;
		}
	}

	return PSCI_INVALID_PWR_LVL;
}

/* MediaTek mcusys power on control interface */
static void armv8_2_mcusys_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
{
	mt_gic_init();
	mt_gic_distif_restore();
	gic_sgi_restore_all();

	dfd_resume();

	/* Add code here that behavior before system enter mcusys'on */
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_MCUSYS)) {
		mtk_cpu_pwr.ops->mcusys_resume(state);
	}
}

/* MediaTek mcusys power down control interface */
static void armv8_2_mcusys_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
{
	mt_gic_distif_save();
	gic_sgi_save_all();

	/* Add code here that behaves before entering mcusys off */
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_MCUSYS)) {
		mtk_cpu_pwr.ops->mcusys_suspend(state);
	}
}

/* MediaTek Cluster power on control interface */
static void armv8_2_cluster_pwr_on_common(const struct mtk_cpupm_pwrstate *state)
{
	/* Add code here that behavior before system enter cluster'on */
#if defined(MTK_CM_MGR) && !defined(MTK_FPGA_EARLY_PORTING)
	/* init cpu stall counter */
	init_cpu_stall_counter_all();
#endif

	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CLUSTER)) {
		mtk_cpu_pwr.ops->cluster_resume(state);
	}
}

/* MediaTek Cluster power down control interface */
static void armv8_2_cluster_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state)
{
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CLUSTER)) {
		mtk_cpu_pwr.ops->cluster_suspend(state);
	}
}

/* MediaTek CPU power on control interface */
static void armv8_2_cpu_pwr_on_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	coordinate_cluster_pwron();

	gicv3_rdistif_on(plat_my_core_pos());
	gicv3_cpuif_enable(plat_my_core_pos());
	mt_gic_rdistif_init();

	/* If MCUSYS has been powered down then restore GIC redistributor for all CPUs. */
	if (IS_PLAT_SYSTEM_RETENTION(state->pwr.afflv)) {
		mt_gic_rdistif_restore_all();
	} else {
		mt_gic_rdistif_restore();
	}
}

/* MediaTek CPU power down control interface */
static void armv8_2_cpu_pwr_dwn_common(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	if ((pstate & MT_CPUPM_PWR_DOMAIN_PERCORE_DSU) != 0) {
		coordinate_cluster_pwroff();
	}

	mt_gic_rdistif_save();
	gicv3_cpuif_disable(plat_my_core_pos());
	gicv3_rdistif_off(plat_my_core_pos());
}

static void armv8_2_cpu_pwr_resume(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	armv8_2_cpu_pwr_on_common(state, pstate);
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_RESUME_CORE)) {
		mtk_cpu_pwr.ops->cpu_resume(state);
	}
}

static void armv8_2_cpu_pwr_suspend(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_SUSPEND_CORE)) {
		mtk_cpu_pwr.ops->cpu_suspend(state);
	}
	armv8_2_cpu_pwr_dwn_common(state, pstate);
}

static void armv8_2_cpu_pwr_on(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	armv8_2_cpu_pwr_on_common(state, pstate);

	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_ON)) {
		mtk_cpu_pwr.smp->cpu_on(state);
	}
}

static void armv8_2_cpu_pwr_off(const struct mtk_cpupm_pwrstate *state, unsigned int pstate)
{
	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_CORE_OFF)) {
		mtk_cpu_pwr.smp->cpu_off(state);
	}
	armv8_2_cpu_pwr_dwn_common(state, pstate);
}

/* MediaTek PSCI power domain */
static int armv8_2_power_domain_on(u_register_t mpidr)
{
	int ret = PSCI_E_SUCCESS;
	int cpu = plat_core_pos_by_mpidr(mpidr);
	uintptr_t entry = plat_pm_get_warm_entry();

	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_PWR_ON_CORE_PREPARE)) {
		if (mtk_cpu_pwr.smp->cpu_pwr_on_prepare(cpu, entry) != 0) {
			ret = PSCI_E_DENIED;
		}
	}
	INFO("CPU %u power domain prepare on\n", cpu);
	return ret;
}

/* MediaTek PSCI power domain */
static void armv8_2_power_domain_on_finish(const psci_power_state_t *state)
{
	struct mt_cpupm_event_data nb;
	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
	struct mtk_cpupm_pwrstate pm_state = {
		.info = {
			.cpuid = plat_my_core_pos(),
			.mode = MTK_CPU_PM_SMP,
		},
		.pwr = {
			.afflv = armv8_2_get_pwr_afflv(state),
			.state_id = 0x0,
		},
	};

	armv8_2_cpu_pwr_on(&pm_state, pstate);

	nb.cpuid = pm_state.info.cpuid;
	nb.pwr_domain = pstate;
	MT_CPUPM_EVENT_PWR_ON(&nb);

	INFO("CPU %u power domain on finished\n", pm_state.info.cpuid);
}

/* MediaTek PSCI power domain */
static void armv8_2_power_domain_off(const psci_power_state_t *state)
{
	struct mt_cpupm_event_data nb;
	unsigned int pstate = (MT_CPUPM_PWR_DOMAIN_CORE | MT_CPUPM_PWR_DOMAIN_PERCORE_DSU);
	struct mtk_cpupm_pwrstate pm_state = {
		.info = {
			.cpuid = plat_my_core_pos(),
			.mode = MTK_CPU_PM_SMP,
		},
		.pwr = {
			.afflv = armv8_2_get_pwr_afflv(state),
			.state_id = 0x0,
		},
	};
	armv8_2_cpu_pwr_off(&pm_state, pstate);

	nb.cpuid = pm_state.info.cpuid;
	nb.pwr_domain = pstate;
	MT_CPUPM_EVENT_PWR_OFF(&nb);

	INFO("CPU %u power domain off\n", pm_state.info.cpuid);
}

/* MediaTek PSCI power domain */
static void armv8_2_power_domain_suspend(const psci_power_state_t *state)
{
	unsigned int pstate = 0;
	struct mt_cpupm_event_data nb;
	struct mtk_cpupm_pwrstate pm_state = {
		.info = {
			.cpuid = plat_my_core_pos(),
			.mode = MTK_CPU_PM_CPUIDLE,
		},
	};

	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
	pm_state.pwr.raw = state;

	pstate = get_mediatek_pstate(CPUPM_PWR_OFF,
				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);

	armv8_2_cpu_pwr_suspend(&pm_state, pstate);

	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
		armv8_2_cluster_pwr_dwn_common(&pm_state);
	}

	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
		armv8_2_mcusys_pwr_dwn_common(&pm_state);
	}

	nb.cpuid = pm_state.info.cpuid;
	nb.pwr_domain = pstate;
	MT_CPUPM_EVENT_PWR_OFF(&nb);

	if (IS_AFFLV_PUBEVENT(pstate)) {
		MT_CPUPM_EVENT_AFFLV_PWR_OFF(&nb);
	}
}

/* MediaTek PSCI power domain */
static void armv8_2_power_domain_suspend_finish(const psci_power_state_t *state)
{
	unsigned int pstate = 0;
	struct mt_cpupm_event_data nb;
	struct mtk_cpupm_pwrstate pm_state = {
		.info = {
			.cpuid = plat_my_core_pos(),
			.mode = MTK_CPU_PM_CPUIDLE,
		},
	};

	pm_state.pwr.state_id = armv8_2_get_pwr_stateid(pm_state.info.cpuid);
	pm_state.pwr.afflv = armv8_2_get_pwr_afflv(state);
	pm_state.pwr.raw = state;

	pstate = get_mediatek_pstate(CPUPM_PWR_ON,
				     armv8_2_power_state[pm_state.info.cpuid], &pm_state);

	if ((pstate & MT_CPUPM_PWR_DOMAIN_MCUSYS) != 0) {
		armv8_2_mcusys_pwr_on_common(&pm_state);
	}

	if ((pstate & MT_CPUPM_PWR_DOMAIN_CLUSTER) != 0) {
		armv8_2_cluster_pwr_on_common(&pm_state);
	}

	armv8_2_cpu_pwr_resume(&pm_state, pstate);

	nb.cpuid = pm_state.info.cpuid;
	nb.pwr_domain = pstate;
	MT_CPUPM_EVENT_PWR_ON(&nb);

	if (IS_AFFLV_PUBEVENT(pstate)) {
		MT_CPUPM_EVENT_AFFLV_PWR_ON(&nb);
	}
}

/* MediaTek PSCI power domain */
static int armv8_2_validate_power_state(unsigned int power_state, psci_power_state_t *req_state)
{
	unsigned int i;
	unsigned int pstate = psci_get_pstate_type(power_state);
	unsigned int aff_lvl = psci_get_pstate_pwrlvl(power_state);
	unsigned int my_core_pos = plat_my_core_pos();

	if (mtk_cpu_pwr.ops == NULL) {
		return PSCI_E_INVALID_PARAMS;
	}

	if (IS_CPUIDLE_FN_ENABLE(MTK_CPUPM_FN_PWR_STATE_VALID)) {
		if (mtk_cpu_pwr.ops->pwr_state_valid(aff_lvl, pstate) != 0) {
			return PSCI_E_INVALID_PARAMS;
		}
	}

	if (pstate == PSTATE_TYPE_STANDBY) {
		req_state->pwr_domain_state[0] = PLAT_MAX_RET_STATE;
	} else {
		for (i = PSCI_CPU_PWR_LVL; i <= aff_lvl; i++) {
			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
		}
	}
	armv8_2_power_state[my_core_pos] = power_state;

	return PSCI_E_SUCCESS;
}

/* MediaTek PSCI power domain */
#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
static void armv8_2_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
	unsigned int i;
	int ret;
	unsigned int power_state;
	unsigned int my_core_pos = plat_my_core_pos();

	ret = mtk_cpu_pwr.ops->pwr_state_valid(PLAT_MAX_PWR_LVL,
						PSTATE_TYPE_POWERDOWN);

	if (ret != MTK_CPUPM_E_OK) {
		/* Avoid suspend due to platform is not ready. */
		req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] =
						PLAT_MAX_RET_STATE;
		for (i = PSCI_CPU_PWR_LVL + 1; i <= PLAT_MAX_PWR_LVL; i++) {
			req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
		}

		power_state = psci_make_powerstate(0, PSTATE_TYPE_STANDBY, PSCI_CPU_PWR_LVL);
	} else {
		for (i = PSCI_CPU_PWR_LVL; i <= PLAT_MAX_PWR_LVL; i++) {
			req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
		}

		power_state = psci_make_powerstate(MT_PLAT_PWR_STATE_SYSTEM_SUSPEND,
						   PSTATE_TYPE_POWERDOWN, PLAT_MAX_PWR_LVL);
	}

	armv8_2_power_state[my_core_pos] = power_state;
	flush_dcache_range((uintptr_t)&armv8_2_power_state[my_core_pos],
			   sizeof(armv8_2_power_state[my_core_pos]));
}
#endif
static void armv8_2_pm_smp_init(unsigned int cpu_id, uintptr_t entry_point)
{
	if (entry_point == 0) {
		ERROR("%s, warm_entry_point is null\n", __func__);
		panic();
	}
	if (IS_CPUSMP_FN_ENABLE(MTK_CPUPM_FN_SMP_INIT)) {
		mtk_cpu_pwr.smp->init(cpu_id, entry_point);
	}
	INFO("[%s:%d] - Initialize finished\n", __func__, __LINE__);
}

static struct plat_pm_pwr_ctrl armv8_2_pwr_ops = {
	.pwr_domain_suspend = armv8_2_power_domain_suspend,
	.pwr_domain_suspend_finish = armv8_2_power_domain_suspend_finish,
	.validate_power_state = armv8_2_validate_power_state,
#if CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND
	.get_sys_suspend_power_state = armv8_2_get_sys_suspend_power_state,
#endif
};

struct plat_pm_smp_ctrl armv8_2_smp_ops = {
	.init = armv8_2_pm_smp_init,
	.pwr_domain_on = armv8_2_power_domain_on,
	.pwr_domain_off = armv8_2_power_domain_off,
	.pwr_domain_on_finish = armv8_2_power_domain_on_finish,
};

#define ISSUE_CPU_PM_REG_FAIL(_success) ({ _success = false; assert(0); })

#define CPM_PM_FN_CHECK(_fns, _ops, _id, _func, _result, _flag) ({ \
	if ((_fns & _id)) { \
		if (_ops->_func) \
			_flag |= _id; \
		else { \
			ISSUE_CPU_PM_REG_FAIL(_result); \
		} \
	} })

int register_cpu_pm_ops(unsigned int fn_flags, struct mtk_cpu_pm_ops *ops)
{
	bool success = true;
	unsigned int fns = 0;

	if ((ops == NULL) || (mtk_cpu_pwr.ops != NULL)) {
		ERROR("[%s:%d] register cpu_pm fail !!\n", __FILE__, __LINE__);
		return MTK_CPUPM_E_ERR;
	}

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CORE,
			cpu_resume, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CORE,
			cpu_suspend, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_CLUSTER,
			cluster_resume, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_CLUSTER,
			cluster_suspend, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_RESUME_MCUSYS,
			mcusys_resume, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SUSPEND_MCUSYS,
			mcusys_suspend, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_CPUPM_GET_PWR_STATE,
			get_pstate, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_STATE_VALID,
			pwr_state_valid, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_INIT,
			init, success, fns);

	if (success) {
		mtk_cpu_pwr.ops = ops;
		mtk_cpu_pwr.fn_mask |= fns;
		plat_pm_ops_setup_pwr(&armv8_2_pwr_ops);
		INFO("[%s:%d] CPU pwr ops register success, support:0x%x\n",
		     __func__, __LINE__, fns);
	} else {
		ERROR("[%s:%d] register cpu_pm ops fail !, fn:0x%x\n",
		      __func__, __LINE__, fn_flags);
		assert(0);
	}
	return MTK_CPUPM_E_OK;
}

int register_cpu_smp_ops(unsigned int fn_flags, struct mtk_cpu_smp_ops *ops)
{
	bool success = true;
	unsigned int fns = 0;

	if ((ops == NULL) || (mtk_cpu_pwr.smp != NULL)) {
		ERROR("[%s:%d] register cpu_smp fail !!\n", __FILE__, __LINE__);
		return MTK_CPUPM_E_ERR;
	}

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_INIT,
			init, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_PWR_ON_CORE_PREPARE,
			cpu_pwr_on_prepare, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_ON,
			cpu_on, success, fns);

	CPM_PM_FN_CHECK(fn_flags, ops, MTK_CPUPM_FN_SMP_CORE_OFF,
			cpu_off, success, fns);

	if (success == true) {
		mtk_cpu_pwr.smp = ops;
		mtk_cpu_pwr.fn_mask |= fns;
		plat_pm_ops_setup_smp(&armv8_2_smp_ops);
		INFO("[%s:%d] CPU smp ops register success, support:0x%x\n",
		     __func__, __LINE__, fns);
	} else {
		ERROR("[%s:%d] register cpu_smp ops fail !, fn:0x%x\n",
		      __func__, __LINE__, fn_flags);
		assert(0);
	}
	return MTK_CPUPM_E_OK;
}
