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