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

#include <arch_helpers.h>
#include <common/debug.h>

#include <mt_lp_rm.h>
#include <mt_spm.h>
#include <mt_spm_cond.h>
#include <mt_spm_constraint.h>
#include <mt_spm_conservation.h>
#include <mt_spm_idle.h>
#include <mt_spm_internal.h>
#include <mt_spm_notifier.h>
#include <mt_spm_rc_internal.h>
#include <mt_spm_resource_req.h>
#include <mt_spm_reg.h>
#include <mt_spm_suspend.h>
#include <plat_pm.h>
#include <plat_mtk_lpm.h>

#ifndef ATF_PLAT_CIRQ_UNSUPPORT
#include <mt_cirq.h>
#include <mt_gic_v3.h>
#endif

#define CONSTRAINT_BUS26M_ALLOW			\
	(MT_RM_CONSTRAINT_ALLOW_CPU_BUCK_OFF |	\
	 MT_RM_CONSTRAINT_ALLOW_DRAM_S0 |	\
	 MT_RM_CONSTRAINT_ALLOW_DRAM_S1 |	\
	 MT_RM_CONSTRAINT_ALLOW_VCORE_LP |	\
	 MT_RM_CONSTRAINT_ALLOW_LVTS_STATE |	\
	 MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF)

#define CONSTRAINT_BUS26M_PCM_FLAG		\
	(SPM_FLAG_DISABLE_INFRA_PDN |		\
	 SPM_FLAG_DISABLE_VCORE_DVS |		\
	 SPM_FLAG_DISABLE_VCORE_DFS |		\
	 SPM_FLAG_SRAM_SLEEP_CTRL |		\
	 SPM_FLAG_ENABLE_TIA_WORKAROUND |	\
	 SPM_FLAG_ENABLE_LVTS_WORKAROUND |	\
	 SPM_FLAG_KEEP_CSYSPWRACK_HIGH |	\
	 SPM_FLAG_DISABLE_DRAMC_MCU_SRAM_SLEEP)

#define CONSTRAINT_BUS26M_PCM_FLAG1		0U

#define CONSTRAINT_BUS26M_RESOURCE_REQ		0U

static unsigned int bus26m_ext_opand;
static struct mt_irqremain *refer2remain_irq;
static struct mt_spm_cond_tables cond_bus26m = {
	.name = "bus26m",
	.table_cg = {
		0xFFFFD408,	/* MTCMOS1 */
		0x2284C802,	/* INFRA0  */
		0x27AF8000,	/* INFRA1  */
		0x86040650,	/* INFRA2  */
		0x30038020,	/* INFRA3  */
		0x80000000,	/* INFRA4  */
		0x00080ABB,	/* PERI0   */
		0x00004000,	/* VPPSYS0_0  */
		0x08803000,	/* VPPSYS0_1  */
		0x00000000,	/* VPPSYS0_2  */
		0x80005555,	/* VPPSYS1_0  */
		0x00009008,	/* VPPSYS1_1  */
		0x60060000,	/* VDOSYS0_0  */
		0x00000000,	/* VDOSYS0_1  */
		0x201E01F8,	/* VDOSYS1_0  */
		0x00800000,	/* VDOSYS1_1  */
		0x00000000,	/* VDOSYS1_2  */
		0x00000080,	/* I2C */
	},
	.table_pll = (PLL_BIT_UNIVPLL |
		      PLL_BIT_MFGPLL |
		      PLL_BIT_MSDCPLL |
		      PLL_BIT_TVDPLL |
		      PLL_BIT_MMPLL),
};

static struct mt_spm_cond_tables cond_bus26m_res = {
	.table_cg = { 0U },
	.table_pll = 0U,
};

static struct constraint_status status = {
	.id = MT_RM_CONSTRAINT_ID_BUS26M,
	.valid = (MT_SPM_RC_VALID_SW |
		  MT_SPM_RC_VALID_COND_LATCH),
	.cond_block = 0U,
	.enter_cnt = 0U,
	.cond_res = &cond_bus26m_res,
};

/*
 * Cirq will take the place of gic when gic is off.
 * However, cirq cannot work if 26m clk is turned off when system idle/suspend.
 * Therefore, we need to set irq pending for specific wakeup source.
 */
#ifdef ATF_PLAT_CIRQ_UNSUPPORT
#define do_irqs_delivery()
#else
static void mt_spm_irq_remain_dump(struct mt_irqremain *irqs,
				   unsigned int irq_index,
				   struct wake_status *wakeup)
{
	INFO("[SPM] r12 = 0x%08x(0x%08x), flag = 0x%08x 0x%08x 0x%08x\n",
	     wakeup->tr.comm.r12, wakeup->md32pcm_wakeup_sta,
	     wakeup->tr.comm.debug_flag, wakeup->tr.comm.b_sw_flag0,
	     wakeup->tr.comm.b_sw_flag1);

	INFO("irq:%u(0x%08x) set pending\n",
	     irqs->wakeupsrc[irq_index], irqs->irqs[irq_index]);
}

static void do_irqs_delivery(void)
{
	unsigned int idx;
	int res = 0;
	struct wake_status *wakeup = NULL;
	struct mt_irqremain *irqs = refer2remain_irq;

	res = spm_conservation_get_result(&wakeup);

	if ((res != 0) && (irqs == NULL)) {
		return;
	}

	for (idx = 0U; idx < irqs->count; ++idx) {
		if (((wakeup->tr.comm.r12 & irqs->wakeupsrc[idx]) != 0U) ||
		    ((wakeup->raw_sta & irqs->wakeupsrc[idx]) != 0U)) {
			if ((irqs->wakeupsrc_cat[idx] &
			     MT_IRQ_REMAIN_CAT_LOG) != 0U) {
				mt_spm_irq_remain_dump(irqs, idx, wakeup);
			}

			mt_irq_set_pending(irqs->irqs[idx]);
		}
	}
}
#endif

static void spm_bus26m_conduct(struct spm_lp_scen *spm_lp,
			       unsigned int *resource_req)
{
	spm_lp->pwrctrl->pcm_flags = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG;
	spm_lp->pwrctrl->pcm_flags1 = (uint32_t)CONSTRAINT_BUS26M_PCM_FLAG1;
	*resource_req |= CONSTRAINT_BUS26M_RESOURCE_REQ;
}

bool spm_is_valid_rc_bus26m(unsigned int cpu, int state_id)
{
	(void)cpu;
	(void)state_id;

	return (status.cond_block == 0U) && IS_MT_RM_RC_READY(status.valid);
}

int spm_update_rc_bus26m(int state_id, int type, const void *val)
{
	const struct mt_spm_cond_tables *tlb;
	const struct mt_spm_cond_tables *tlb_check;
	int res = MT_RM_STATUS_OK;

	if (val == NULL) {
		return MT_RM_STATUS_BAD;
	}

	if (type == PLAT_RC_UPDATE_CONDITION) {
		tlb = (const struct mt_spm_cond_tables *)val;
		tlb_check = (const struct mt_spm_cond_tables *)&cond_bus26m;

		status.cond_block =
			mt_spm_cond_check(state_id, tlb, tlb_check,
					  ((status.valid &
					    MT_SPM_RC_VALID_COND_LATCH) != 0U) ?
					  &cond_bus26m_res : NULL);
	} else if (type == PLAT_RC_UPDATE_REMAIN_IRQS) {
		refer2remain_irq = (struct mt_irqremain *)val;
	} else {
		res = MT_RM_STATUS_BAD;
	}

	return res;
}

unsigned int spm_allow_rc_bus26m(int state_id)
{
	(void)state_id;

	return CONSTRAINT_BUS26M_ALLOW;
}

int spm_run_rc_bus26m(unsigned int cpu, int state_id)
{
	(void)cpu;

#ifndef ATF_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_ENTER, CONSTRAINT_BUS26M_ALLOW |
			       (IS_PLAT_SUSPEND_ID(state_id) ?
				MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND : 0U));
#endif
	if (IS_PLAT_SUSPEND_ID(state_id)) {
		mt_spm_suspend_enter(state_id,
				     (MT_SPM_EX_OP_SET_WDT |
				      MT_SPM_EX_OP_HW_S1_DETECT |
				      MT_SPM_EX_OP_SET_SUSPEND_MODE |
				      bus26m_ext_opand),
				     CONSTRAINT_BUS26M_RESOURCE_REQ);
	} else {
		mt_spm_idle_generic_enter(state_id, MT_SPM_EX_OP_HW_S1_DETECT,
					  spm_bus26m_conduct);
	}

	return 0;
}

int spm_reset_rc_bus26m(unsigned int cpu, int state_id)
{
	unsigned int ext_op = MT_SPM_EX_OP_HW_S1_DETECT;

	(void)cpu;

#ifndef ATF_PLAT_SPM_SSPM_NOTIFIER_UNSUPPORT
	mt_spm_sspm_notify_u32(MT_SPM_NOTIFY_LP_LEAVE, 0U);
#endif
	if (IS_PLAT_SUSPEND_ID(state_id)) {
		ext_op |= (bus26m_ext_opand | MT_SPM_EX_OP_SET_WDT);
		mt_spm_suspend_resume(state_id, ext_op, NULL);
		bus26m_ext_opand = 0U;
	} else {
		mt_spm_idle_generic_resume(state_id, ext_op, NULL);
		status.enter_cnt++;
	}

	do_irqs_delivery();

	return 0;
}
