/*
 * Copyright (c) 2020, 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_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(0x0094)
#define	INFRA_SW_CG1			MT_LP_TZ_INFRA_REG(0x0090)
#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(0x00D8)
#define INFRA_SW_CG5                    MT_LP_TZ_INFRA_REG(0x00E8)
#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)

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

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

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

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

	return false;
}

static struct mt_spm_cond_tables spm_cond_t;

struct idle_cond_info {
	unsigned int subsys_mask;
	uintptr_t addr;
	bool bBitflip;
	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(0x00100000, MMSYS_CG_CON0, true, (CLK_CHECK | CLKMUX_DISP)),
	IDLE_CG(0x00100000, MMSYS_CG_CON1, true, (CLK_CHECK | CLKMUX_DISP)),
	IDLE_CG(0x00100000, MMSYS_CG_CON2, true, (CLK_CHECK | CLKMUX_DISP)),
};

/***********************************************************
 * Check pll idle condition
 ***********************************************************/
#define PLL_MFGPLL	MT_LP_TZ_APMIXEDSYS(0x268)
#define PLL_MMPLL	MT_LP_TZ_APMIXEDSYS(0x360)
#define PLL_UNIVPLL	MT_LP_TZ_APMIXEDSYS(0x308)
#define PLL_MSDCPLL	MT_LP_TZ_APMIXEDSYS(0x350)
#define PLL_TVDPLL	MT_LP_TZ_APMIXEDSYS(0x380)

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, i;
	bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id);

	if ((src == NULL) || (dest == NULL)) {
		return SPM_COND_CHECK_FAIL;
	}

	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 |= (1U << i);
			}
		} else if ((src->table_cg[i] & dest->table_cg[i]) != 0U) {
			blocked |= (1U << 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].bBitflip ?
					 ~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;
}
