/*
 * Copyright (c) 2022, 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, 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;
}
