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

#include <stdbool.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <mt_spm_cond.h>
#include <mt_spm_conservation.h>
#include <mt_spm_constraint.h>
#include <plat_mtk_lpm.h>
#include <plat_pm.h>
#include <platform_def.h>

#define MT_LP_TZ_INFRA_REG(ofs)		(INFRACFG_AO_BASE + ofs)
#define MT_LP_TZ_MM_REG(ofs)		(MMSYS_BASE + ofs)
#define MT_LP_TZ_MDP_REG(ofs)		(MDPSYS_BASE + ofs)
#define MT_LP_TZ_SPM_REG(ofs)		(SPM_BASE + ofs)
#define MT_LP_TZ_TOPCK_REG(ofs)		(TOPCKGEN_BASE + ofs)
#define MT_LP_TZ_APMIXEDSYS(ofs)	(APMIXEDSYS + ofs)

#define SPM_PWR_STATUS			MT_LP_TZ_SPM_REG(0x016C)
#define SPM_PWR_STATUS_2ND		MT_LP_TZ_SPM_REG(0x0170)
#define	INFRA_SW_CG0			MT_LP_TZ_INFRA_REG(0x0090)
#define	INFRA_SW_CG1			MT_LP_TZ_INFRA_REG(0x0094)
#define	INFRA_SW_CG2			MT_LP_TZ_INFRA_REG(0x00AC)
#define	INFRA_SW_CG3			MT_LP_TZ_INFRA_REG(0x00C8)
#define INFRA_SW_CG4                    MT_LP_TZ_INFRA_REG(0x00E8)
#define INFRA_SW_CG5                    MT_LP_TZ_INFRA_REG(0x00D8)
#define MMSYS_CG_CON0			MT_LP_TZ_MM_REG(0x100)
#define MMSYS_CG_CON1			MT_LP_TZ_MM_REG(0x110)
#define MMSYS_CG_CON2                   MT_LP_TZ_MM_REG(0x1A0)
#define MMSYS_CG_CON3			MT_LP_TZ_MDP_REG(0x100)

/* Check clkmux registers */
#define CLK_CFG(id)    MT_LP_TZ_TOPCK_REG(0xe0 + id * 0x10)
#define CLK_CHECK      BIT(31)

enum {
	CLKMUX_DISP  = 0,
	CLKMUX_MDP   = 1,
	CLKMUX_IMG1  = 2,
	CLKMUX_IMG2  = 3,
	NF_CLKMUX    = 4,
};

static bool is_clkmux_pdn(unsigned int clkmux_id)
{
	unsigned int reg, val, idx;
	bool ret = false;

	if (clkmux_id & CLK_CHECK) {
		clkmux_id = (clkmux_id & ~CLK_CHECK);
		reg = clkmux_id / 4U;
		val = mmio_read_32(CLK_CFG(reg));
		idx = clkmux_id % 4U;
		ret = (((val >> (idx * 8U)) & 0x80) != 0U);
	}

	return ret;
}

static struct mt_spm_cond_tables spm_cond_t;

struct idle_cond_info {
	unsigned int subsys_mask;
	uintptr_t addr;
	bool bit_flip;
	unsigned int clkmux_id;
};

#define IDLE_CG(mask, addr, bitflip, clkmux)	\
	{mask, (uintptr_t)addr, bitflip, clkmux}

static struct idle_cond_info idle_cg_info[PLAT_SPM_COND_MAX] = {
	IDLE_CG(0xffffffff, SPM_PWR_STATUS, false, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG0, true, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG1, true, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG2, true, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG3, true, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG4, true, 0U),
	IDLE_CG(0x00000200, INFRA_SW_CG5, true, 0U),
	IDLE_CG(0x00200000, MMSYS_CG_CON0, true, (CLK_CHECK | CLKMUX_DISP)),
	IDLE_CG(0x00200000, MMSYS_CG_CON1, true, (CLK_CHECK | CLKMUX_DISP)),
	IDLE_CG(0x00200000, MMSYS_CG_CON2, true, (CLK_CHECK | CLKMUX_DISP)),
	IDLE_CG(0x00200000, MMSYS_CG_CON3, true, (CLK_CHECK | CLKMUX_MDP)),
};

/* Check pll idle condition */
#define PLL_MFGPLL	MT_LP_TZ_APMIXEDSYS(0x314)
#define PLL_MMPLL	MT_LP_TZ_APMIXEDSYS(0x254)
#define PLL_UNIVPLL	MT_LP_TZ_APMIXEDSYS(0x324)
#define PLL_MSDCPLL	MT_LP_TZ_APMIXEDSYS(0x38c)
#define PLL_TVDPLL	MT_LP_TZ_APMIXEDSYS(0x264)

unsigned int mt_spm_cond_check(int state_id,
			       const struct mt_spm_cond_tables *src,
			       const struct mt_spm_cond_tables *dest,
			       struct mt_spm_cond_tables *res)
{
	unsigned int blocked = 0U;
	unsigned int i;
	bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id);

	if ((src == NULL) || (dest == NULL)) {
		blocked = SPM_COND_CHECK_FAIL;
	} else {
		for (i = 0U; i < PLAT_SPM_COND_MAX; i++) {
			if (res != NULL) {
				res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]);
				if (is_system_suspend && ((res->table_cg[i]) != 0U)) {
					INFO("suspend: %s block[%u](0x%lx) = 0x%08x\n",
					     dest->name, i, idle_cg_info[i].addr,
					     res->table_cg[i]);
				}

				if ((res->table_cg[i]) != 0U) {
					blocked |= BIT(i);
				}
			} else if ((src->table_cg[i] & dest->table_cg[i]) != 0U) {
				blocked |= BIT(i);
				break;
			}
		}

		if (res != NULL) {
			res->table_pll = (src->table_pll & dest->table_pll);

			if (res->table_pll != 0U) {
				blocked |= (res->table_pll << SPM_COND_BLOCKED_PLL_IDX) |
					    SPM_COND_CHECK_BLOCKED_PLL;
			}
		} else if ((src->table_pll & dest->table_pll) != 0U) {
			blocked |= SPM_COND_CHECK_BLOCKED_PLL;
		}

		if (is_system_suspend && ((blocked) != 0U)) {
			INFO("suspend: %s total blocked = 0x%08x\n", dest->name, blocked);
		}
	}

	return blocked;
}

#define IS_MT_SPM_PWR_OFF(mask)					\
	(((mmio_read_32(SPM_PWR_STATUS) & mask) == 0U) &&	\
	 ((mmio_read_32(SPM_PWR_STATUS_2ND) & mask) == 0U))

int mt_spm_cond_update(struct mt_resource_constraint **con, unsigned int num,
		       int stateid, void *priv)
{
	int res;
	uint32_t i;
	struct mt_resource_constraint *const *rc;

	/* read all cg state */
	for (i = 0U; i < PLAT_SPM_COND_MAX; i++) {
		spm_cond_t.table_cg[i] = 0U;

		/* check mtcmos, if off set idle_value and clk to 0 disable */
		if (IS_MT_SPM_PWR_OFF(idle_cg_info[i].subsys_mask)) {
			continue;
		}

		/* check clkmux */
		if (is_clkmux_pdn(idle_cg_info[i].clkmux_id)) {
			continue;
		}

		spm_cond_t.table_cg[i] = idle_cg_info[i].bit_flip ?
					 ~mmio_read_32(idle_cg_info[i].addr) :
					 mmio_read_32(idle_cg_info[i].addr);
	}

	spm_cond_t.table_pll = 0U;
	if ((mmio_read_32(PLL_MFGPLL) & 0x1) != 0U) {
		spm_cond_t.table_pll |= PLL_BIT_MFGPLL;
	}

	if ((mmio_read_32(PLL_MMPLL) & 0x1) != 0U) {
		spm_cond_t.table_pll |= PLL_BIT_MMPLL;
	}

	if ((mmio_read_32(PLL_UNIVPLL) & 0x1) != 0U) {
		spm_cond_t.table_pll |= PLL_BIT_UNIVPLL;
	}

	if ((mmio_read_32(PLL_MSDCPLL) & 0x1) != 0U) {
		spm_cond_t.table_pll |= PLL_BIT_MSDCPLL;
	}

	if ((mmio_read_32(PLL_TVDPLL) & 0x1) != 0U) {
		spm_cond_t.table_pll |= PLL_BIT_TVDPLL;
	}

	spm_cond_t.priv = priv;

	for (rc = con; *rc != NULL; rc++) {
		if (((*rc)->update) == NULL) {
			continue;
		}

		res = (*rc)->update(stateid, PLAT_RC_UPDATE_CONDITION,
				    (void const *)&spm_cond_t);
		if (res != MT_RM_STATUS_OK) {
			break;
		}
	}

	return 0;
}
