xref: /openbmc/u-boot/arch/arm/mach-socfpga/freeze_controller.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
205a21721SMasahiro Yamada /*
305a21721SMasahiro Yamada  *  Copyright (C) 2013 Altera Corporation <www.altera.com>
405a21721SMasahiro Yamada  */
505a21721SMasahiro Yamada 
605a21721SMasahiro Yamada 
705a21721SMasahiro Yamada #include <common.h>
805a21721SMasahiro Yamada #include <asm/io.h>
9a8535c30SMarek Vasut #include <asm/arch/clock_manager.h>
1005a21721SMasahiro Yamada #include <asm/arch/freeze_controller.h>
111221ce45SMasahiro Yamada #include <linux/errno.h>
1205a21721SMasahiro Yamada 
1305a21721SMasahiro Yamada static const struct socfpga_freeze_controller *freeze_controller_base =
1405a21721SMasahiro Yamada 		(void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
1505a21721SMasahiro Yamada 
1605a21721SMasahiro Yamada /*
1705a21721SMasahiro Yamada  * Default state from cold reset is FREEZE_ALL; the global
1805a21721SMasahiro Yamada  * flag is set to TRUE to indicate the IO banks are frozen
1905a21721SMasahiro Yamada  */
2005a21721SMasahiro Yamada static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
2105a21721SMasahiro Yamada 	= { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
2205a21721SMasahiro Yamada 	FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};
2305a21721SMasahiro Yamada 
2405a21721SMasahiro Yamada /* Freeze HPS IOs */
sys_mgr_frzctrl_freeze_req(void)2505a21721SMasahiro Yamada void sys_mgr_frzctrl_freeze_req(void)
2605a21721SMasahiro Yamada {
2705a21721SMasahiro Yamada 	u32 ioctrl_reg_offset;
2805a21721SMasahiro Yamada 	u32 reg_value;
2905a21721SMasahiro Yamada 	u32 reg_cfg_mask;
3005a21721SMasahiro Yamada 	u32 channel_id;
3105a21721SMasahiro Yamada 
3205a21721SMasahiro Yamada 	/* select software FSM */
3305a21721SMasahiro Yamada 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
3405a21721SMasahiro Yamada 
3505a21721SMasahiro Yamada 	/* Freeze channel 0 to 2 */
3605a21721SMasahiro Yamada 	for (channel_id = 0; channel_id <= 2; channel_id++) {
3705a21721SMasahiro Yamada 		ioctrl_reg_offset = (u32)(
3805a21721SMasahiro Yamada 			&freeze_controller_base->vioctrl + channel_id);
3905a21721SMasahiro Yamada 
4005a21721SMasahiro Yamada 		/*
4105a21721SMasahiro Yamada 		 * Assert active low enrnsl, plniotri
4205a21721SMasahiro Yamada 		 * and niotri signals
4305a21721SMasahiro Yamada 		 */
4405a21721SMasahiro Yamada 		reg_cfg_mask =
4505a21721SMasahiro Yamada 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK
4605a21721SMasahiro Yamada 			| SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
4705a21721SMasahiro Yamada 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
4805a21721SMasahiro Yamada 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
4905a21721SMasahiro Yamada 
5005a21721SMasahiro Yamada 		/*
5105a21721SMasahiro Yamada 		 * Note: Delay for 20ns at min
5205a21721SMasahiro Yamada 		 * Assert active low bhniotri signal and de-assert
5305a21721SMasahiro Yamada 		 * active high csrdone
5405a21721SMasahiro Yamada 		 */
5505a21721SMasahiro Yamada 		reg_cfg_mask
5605a21721SMasahiro Yamada 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
5705a21721SMasahiro Yamada 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
5805a21721SMasahiro Yamada 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
5905a21721SMasahiro Yamada 
6005a21721SMasahiro Yamada 		/* Set global flag to indicate channel is frozen */
6105a21721SMasahiro Yamada 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
6205a21721SMasahiro Yamada 	}
6305a21721SMasahiro Yamada 
6405a21721SMasahiro Yamada 	/* Freeze channel 3 */
6505a21721SMasahiro Yamada 	/*
6605a21721SMasahiro Yamada 	 * Assert active low enrnsl, plniotri and
6705a21721SMasahiro Yamada 	 * niotri signals
6805a21721SMasahiro Yamada 	 */
6905a21721SMasahiro Yamada 	reg_cfg_mask
7005a21721SMasahiro Yamada 		= SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK
7105a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
7205a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
7305a21721SMasahiro Yamada 	clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
7405a21721SMasahiro Yamada 
7505a21721SMasahiro Yamada 	/*
7605a21721SMasahiro Yamada 	 * assert active low bhniotri & nfrzdrv signals,
7705a21721SMasahiro Yamada 	 * de-assert active high csrdone and assert
7805a21721SMasahiro Yamada 	 * active high frzreg and nfrzdrv signals
7905a21721SMasahiro Yamada 	 */
8005a21721SMasahiro Yamada 	reg_value = readl(&freeze_controller_base->hioctrl);
8105a21721SMasahiro Yamada 	reg_cfg_mask
8205a21721SMasahiro Yamada 		= SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
8305a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
8405a21721SMasahiro Yamada 	reg_value
8505a21721SMasahiro Yamada 		= (reg_value & ~reg_cfg_mask)
8605a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK
8705a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
8805a21721SMasahiro Yamada 	writel(reg_value, &freeze_controller_base->hioctrl);
8905a21721SMasahiro Yamada 
9005a21721SMasahiro Yamada 	/*
9105a21721SMasahiro Yamada 	 * assert active high reinit signal and de-assert
9205a21721SMasahiro Yamada 	 * active high pllbiasen signals
9305a21721SMasahiro Yamada 	 */
9405a21721SMasahiro Yamada 	reg_value = readl(&freeze_controller_base->hioctrl);
9505a21721SMasahiro Yamada 	reg_value
9605a21721SMasahiro Yamada 		= (reg_value &
9705a21721SMasahiro Yamada 		~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
9805a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
9905a21721SMasahiro Yamada 	writel(reg_value, &freeze_controller_base->hioctrl);
10005a21721SMasahiro Yamada 
10105a21721SMasahiro Yamada 	/* Set global flag to indicate channel is frozen */
10205a21721SMasahiro Yamada 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
10305a21721SMasahiro Yamada }
10405a21721SMasahiro Yamada 
10505a21721SMasahiro Yamada /* Unfreeze/Thaw HPS IOs */
sys_mgr_frzctrl_thaw_req(void)10605a21721SMasahiro Yamada void sys_mgr_frzctrl_thaw_req(void)
10705a21721SMasahiro Yamada {
10805a21721SMasahiro Yamada 	u32 ioctrl_reg_offset;
10905a21721SMasahiro Yamada 	u32 reg_cfg_mask;
11005a21721SMasahiro Yamada 	u32 reg_value;
11105a21721SMasahiro Yamada 	u32 channel_id;
112a8535c30SMarek Vasut 	unsigned long eosc1_freq;
11305a21721SMasahiro Yamada 
11405a21721SMasahiro Yamada 	/* select software FSM */
11505a21721SMasahiro Yamada 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
11605a21721SMasahiro Yamada 
11705a21721SMasahiro Yamada 	/* Thaw channel 0 to 2 */
11805a21721SMasahiro Yamada 	for (channel_id = 0; channel_id <= 2; channel_id++) {
11905a21721SMasahiro Yamada 		ioctrl_reg_offset
12005a21721SMasahiro Yamada 			= (u32)(&freeze_controller_base->vioctrl + channel_id);
12105a21721SMasahiro Yamada 
12205a21721SMasahiro Yamada 		/*
12305a21721SMasahiro Yamada 		 * Assert active low bhniotri signal and
12405a21721SMasahiro Yamada 		 * de-assert active high csrdone
12505a21721SMasahiro Yamada 		 */
12605a21721SMasahiro Yamada 		reg_cfg_mask
12705a21721SMasahiro Yamada 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
12805a21721SMasahiro Yamada 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
12905a21721SMasahiro Yamada 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
13005a21721SMasahiro Yamada 
13105a21721SMasahiro Yamada 		/*
13205a21721SMasahiro Yamada 		 * Note: Delay for 20ns at min
13305a21721SMasahiro Yamada 		 * de-assert active low plniotri and niotri signals
13405a21721SMasahiro Yamada 		 */
13505a21721SMasahiro Yamada 		reg_cfg_mask
13605a21721SMasahiro Yamada 			= SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
13705a21721SMasahiro Yamada 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
13805a21721SMasahiro Yamada 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
13905a21721SMasahiro Yamada 
14005a21721SMasahiro Yamada 		/*
14105a21721SMasahiro Yamada 		 * Note: Delay for 20ns at min
14205a21721SMasahiro Yamada 		 * de-assert active low enrnsl signal
14305a21721SMasahiro Yamada 		 */
14405a21721SMasahiro Yamada 		setbits_le32(ioctrl_reg_offset,
14505a21721SMasahiro Yamada 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);
14605a21721SMasahiro Yamada 
14705a21721SMasahiro Yamada 		/* Set global flag to indicate channel is thawed */
14805a21721SMasahiro Yamada 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
14905a21721SMasahiro Yamada 	}
15005a21721SMasahiro Yamada 
15105a21721SMasahiro Yamada 	/* Thaw channel 3 */
15205a21721SMasahiro Yamada 	/* de-assert active high reinit signal */
15305a21721SMasahiro Yamada 	clrbits_le32(&freeze_controller_base->hioctrl,
15405a21721SMasahiro Yamada 		SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
15505a21721SMasahiro Yamada 
15605a21721SMasahiro Yamada 	/*
15705a21721SMasahiro Yamada 	 * Note: Delay for 40ns at min
15805a21721SMasahiro Yamada 	 * assert active high pllbiasen signals
15905a21721SMasahiro Yamada 	 */
16005a21721SMasahiro Yamada 	setbits_le32(&freeze_controller_base->hioctrl,
16105a21721SMasahiro Yamada 		SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
16205a21721SMasahiro Yamada 
163a8535c30SMarek Vasut 	/* Delay 1000 intosc cycles. The intosc is based on eosc1. */
164a8535c30SMarek Vasut 	eosc1_freq = cm_get_osc_clk_hz(1) / 1000;	/* kHz */
165a8535c30SMarek Vasut 	udelay(DIV_ROUND_UP(1000000, eosc1_freq));
16605a21721SMasahiro Yamada 
16705a21721SMasahiro Yamada 	/*
16805a21721SMasahiro Yamada 	 * de-assert active low bhniotri signals,
16905a21721SMasahiro Yamada 	 * assert active high csrdone and nfrzdrv signal
17005a21721SMasahiro Yamada 	 */
17105a21721SMasahiro Yamada 	reg_value = readl(&freeze_controller_base->hioctrl);
17205a21721SMasahiro Yamada 	reg_value = (reg_value
17305a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
17405a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK)
17505a21721SMasahiro Yamada 		& ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
17605a21721SMasahiro Yamada 	writel(reg_value, &freeze_controller_base->hioctrl);
17705a21721SMasahiro Yamada 
17805a21721SMasahiro Yamada 	/*
17905a21721SMasahiro Yamada 	 * Delay 33 intosc
18005a21721SMasahiro Yamada 	 * Use worst case which is fatest eosc1=50MHz, delay required
18105a21721SMasahiro Yamada 	 * is 1/50MHz * 33 = 660ns ~= 1us
18205a21721SMasahiro Yamada 	 */
18305a21721SMasahiro Yamada 	udelay(1);
18405a21721SMasahiro Yamada 
18505a21721SMasahiro Yamada 	/* de-assert active low plniotri and niotri signals */
18605a21721SMasahiro Yamada 	reg_cfg_mask
18705a21721SMasahiro Yamada 		= SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
18805a21721SMasahiro Yamada 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
18905a21721SMasahiro Yamada 
19005a21721SMasahiro Yamada 	setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
19105a21721SMasahiro Yamada 
19205a21721SMasahiro Yamada 	/*
19305a21721SMasahiro Yamada 	 * Note: Delay for 40ns at min
19405a21721SMasahiro Yamada 	 * de-assert active high frzreg signal
19505a21721SMasahiro Yamada 	 */
19605a21721SMasahiro Yamada 	clrbits_le32(&freeze_controller_base->hioctrl,
19705a21721SMasahiro Yamada 		SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);
19805a21721SMasahiro Yamada 
19905a21721SMasahiro Yamada 	/*
20005a21721SMasahiro Yamada 	 * Note: Delay for 40ns at min
20105a21721SMasahiro Yamada 	 * de-assert active low enrnsl signal
20205a21721SMasahiro Yamada 	 */
20305a21721SMasahiro Yamada 	setbits_le32(&freeze_controller_base->hioctrl,
20405a21721SMasahiro Yamada 		SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);
20505a21721SMasahiro Yamada 
20605a21721SMasahiro Yamada 	/* Set global flag to indicate channel is thawed */
20705a21721SMasahiro Yamada 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
20805a21721SMasahiro Yamada }
209