diff options
Diffstat (limited to 'arch/arm/cpu/armv7/socfpga/freeze_controller.c')
| -rw-r--r-- | arch/arm/cpu/armv7/socfpga/freeze_controller.c | 215 | 
1 files changed, 215 insertions, 0 deletions
| diff --git a/arch/arm/cpu/armv7/socfpga/freeze_controller.c b/arch/arm/cpu/armv7/socfpga/freeze_controller.c new file mode 100644 index 000000000..b8c9bce1e --- /dev/null +++ b/arch/arm/cpu/armv7/socfpga/freeze_controller.c @@ -0,0 +1,215 @@ +/* + *  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 << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); + +		/* +		 * 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 << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); + +		/* +		 * 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; +} |