/*
 *  Copyright (C) 2013 Altera Corporation <www.altera.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */


#include <common.h>
#include <asm/io.h>
#include <asm/arch/freeze_controller.h>
#include <asm/arch/timer.h>
#include <asm/errno.h>

DECLARE_GLOBAL_DATA_PTR;

static const struct socfpga_freeze_controller *freeze_controller_base =
		(void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);

/*
 * Default state from cold reset is FREEZE_ALL; the global
 * flag is set to TRUE to indicate the IO banks are frozen
 */
static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
	= { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
	FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};

/* Freeze HPS IOs */
void sys_mgr_frzctrl_freeze_req(void)
{
	u32 ioctrl_reg_offset;
	u32 reg_value;
	u32 reg_cfg_mask;
	u32 channel_id;

	/* select software FSM */
	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);

	/* Freeze channel 0 to 2 */
	for (channel_id = 0; channel_id <= 2; channel_id++) {
		ioctrl_reg_offset = (u32)(
			&freeze_controller_base->vioctrl + channel_id);

		/*
		 * Assert active low enrnsl, plniotri
		 * and niotri signals
		 */
		reg_cfg_mask =
			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK
			| SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);

		/*
		 * Note: Delay for 20ns at min
		 * Assert active low bhniotri signal and de-assert
		 * active high csrdone
		 */
		reg_cfg_mask
			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);

		/* Set global flag to indicate channel is frozen */
		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
	}

	/* Freeze channel 3 */
	/*
	 * Assert active low enrnsl, plniotri and
	 * niotri signals
	 */
	reg_cfg_mask
		= SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
	clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);

	/*
	 * assert active low bhniotri & nfrzdrv signals,
	 * de-assert active high csrdone and assert
	 * active high frzreg and nfrzdrv signals
	 */
	reg_value = readl(&freeze_controller_base->hioctrl);
	reg_cfg_mask
		= SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
	reg_value
		= (reg_value & ~reg_cfg_mask)
		| SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
	writel(reg_value, &freeze_controller_base->hioctrl);

	/*
	 * assert active high reinit signal and de-assert
	 * active high pllbiasen signals
	 */
	reg_value = readl(&freeze_controller_base->hioctrl);
	reg_value
		= (reg_value &
		~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
		| SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
	writel(reg_value, &freeze_controller_base->hioctrl);

	/* Set global flag to indicate channel is frozen */
	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
}

/* Unfreeze/Thaw HPS IOs */
void sys_mgr_frzctrl_thaw_req(void)
{
	u32 ioctrl_reg_offset;
	u32 reg_cfg_mask;
	u32 reg_value;
	u32 channel_id;

	/* select software FSM */
	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);

	/* Thaw channel 0 to 2 */
	for (channel_id = 0; channel_id <= 2; channel_id++) {
		ioctrl_reg_offset
			= (u32)(&freeze_controller_base->vioctrl + channel_id);

		/*
		 * Assert active low bhniotri signal and
		 * de-assert active high csrdone
		 */
		reg_cfg_mask
			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);

		/*
		 * Note: Delay for 20ns at min
		 * de-assert active low plniotri and niotri signals
		 */
		reg_cfg_mask
			= SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);

		/*
		 * Note: Delay for 20ns at min
		 * de-assert active low enrnsl signal
		 */
		setbits_le32(ioctrl_reg_offset,
			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);

		/* Set global flag to indicate channel is thawed */
		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
	}

	/* Thaw channel 3 */
	/* de-assert active high reinit signal */
	clrbits_le32(&freeze_controller_base->hioctrl,
		SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);

	/*
	 * Note: Delay for 40ns at min
	 * assert active high pllbiasen signals
	 */
	setbits_le32(&freeze_controller_base->hioctrl,
		SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);

	/*
	 * Delay 1000 intosc. intosc is based on eosc1
	 * Use worst case which is fatest eosc1=50MHz, delay required
	 * is 1/50MHz * 1000 = 20us
	 */
	udelay(20);

	/*
	 * de-assert active low bhniotri signals,
	 * assert active high csrdone and nfrzdrv signal
	 */
	reg_value = readl(&freeze_controller_base->hioctrl);
	reg_value = (reg_value
		| SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK)
		& ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
	writel(reg_value, &freeze_controller_base->hioctrl);

	/*
	 * Delay 33 intosc
	 * Use worst case which is fatest eosc1=50MHz, delay required
	 * is 1/50MHz * 33 = 660ns ~= 1us
	 */
	udelay(1);

	/* de-assert active low plniotri and niotri signals */
	reg_cfg_mask
		= SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;

	setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);

	/*
	 * Note: Delay for 40ns at min
	 * de-assert active high frzreg signal
	 */
	clrbits_le32(&freeze_controller_base->hioctrl,
		SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);

	/*
	 * Note: Delay for 40ns at min
	 * de-assert active low enrnsl signal
	 */
	setbits_le32(&freeze_controller_base->hioctrl,
		SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);

	/* Set global flag to indicate channel is thawed */
	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
}
