1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Copyright (C) 2013 Altera Corporation <www.altera.com>
4  */
5 
6 
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/arch/clock_manager.h>
10 #include <asm/arch/freeze_controller.h>
11 #include <linux/delay.h>
12 #include <linux/errno.h>
13 
14 static const struct socfpga_freeze_controller *freeze_controller_base =
15 		(void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
16 
17 /*
18  * Default state from cold reset is FREEZE_ALL; the global
19  * flag is set to TRUE to indicate the IO banks are frozen
20  */
21 static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
22 	= { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
23 	FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};
24 
25 /* Freeze HPS IOs */
sys_mgr_frzctrl_freeze_req(void)26 void sys_mgr_frzctrl_freeze_req(void)
27 {
28 	u32 ioctrl_reg_offset;
29 	u32 reg_value;
30 	u32 reg_cfg_mask;
31 	u32 channel_id;
32 
33 	/* select software FSM */
34 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
35 
36 	/* Freeze channel 0 to 2 */
37 	for (channel_id = 0; channel_id <= 2; channel_id++) {
38 		ioctrl_reg_offset = (u32)(
39 			&freeze_controller_base->vioctrl + channel_id);
40 
41 		/*
42 		 * Assert active low enrnsl, plniotri
43 		 * and niotri signals
44 		 */
45 		reg_cfg_mask =
46 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK
47 			| SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
48 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
49 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
50 
51 		/*
52 		 * Note: Delay for 20ns at min
53 		 * Assert active low bhniotri signal and de-assert
54 		 * active high csrdone
55 		 */
56 		reg_cfg_mask
57 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
58 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
59 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
60 
61 		/* Set global flag to indicate channel is frozen */
62 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
63 	}
64 
65 	/* Freeze channel 3 */
66 	/*
67 	 * Assert active low enrnsl, plniotri and
68 	 * niotri signals
69 	 */
70 	reg_cfg_mask
71 		= SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK
72 		| SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
73 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
74 	clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
75 
76 	/*
77 	 * assert active low bhniotri & nfrzdrv signals,
78 	 * de-assert active high csrdone and assert
79 	 * active high frzreg and nfrzdrv signals
80 	 */
81 	reg_value = readl(&freeze_controller_base->hioctrl);
82 	reg_cfg_mask
83 		= SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
84 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
85 	reg_value
86 		= (reg_value & ~reg_cfg_mask)
87 		| SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK
88 		| SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
89 	writel(reg_value, &freeze_controller_base->hioctrl);
90 
91 	/*
92 	 * assert active high reinit signal and de-assert
93 	 * active high pllbiasen signals
94 	 */
95 	reg_value = readl(&freeze_controller_base->hioctrl);
96 	reg_value
97 		= (reg_value &
98 		~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
99 		| SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
100 	writel(reg_value, &freeze_controller_base->hioctrl);
101 
102 	/* Set global flag to indicate channel is frozen */
103 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
104 }
105 
106 /* Unfreeze/Thaw HPS IOs */
sys_mgr_frzctrl_thaw_req(void)107 void sys_mgr_frzctrl_thaw_req(void)
108 {
109 	u32 ioctrl_reg_offset;
110 	u32 reg_cfg_mask;
111 	u32 reg_value;
112 	u32 channel_id;
113 	unsigned long eosc1_freq;
114 
115 	/* select software FSM */
116 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
117 
118 	/* Thaw channel 0 to 2 */
119 	for (channel_id = 0; channel_id <= 2; channel_id++) {
120 		ioctrl_reg_offset
121 			= (u32)(&freeze_controller_base->vioctrl + channel_id);
122 
123 		/*
124 		 * Assert active low bhniotri signal and
125 		 * de-assert active high csrdone
126 		 */
127 		reg_cfg_mask
128 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
129 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
130 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
131 
132 		/*
133 		 * Note: Delay for 20ns at min
134 		 * de-assert active low plniotri and niotri signals
135 		 */
136 		reg_cfg_mask
137 			= SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
138 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
139 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
140 
141 		/*
142 		 * Note: Delay for 20ns at min
143 		 * de-assert active low enrnsl signal
144 		 */
145 		setbits_le32(ioctrl_reg_offset,
146 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);
147 
148 		/* Set global flag to indicate channel is thawed */
149 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
150 	}
151 
152 	/* Thaw channel 3 */
153 	/* de-assert active high reinit signal */
154 	clrbits_le32(&freeze_controller_base->hioctrl,
155 		SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
156 
157 	/*
158 	 * Note: Delay for 40ns at min
159 	 * assert active high pllbiasen signals
160 	 */
161 	setbits_le32(&freeze_controller_base->hioctrl,
162 		SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
163 
164 	/* Delay 1000 intosc cycles. The intosc is based on eosc1. */
165 	eosc1_freq = cm_get_osc_clk_hz(1) / 1000;	/* kHz */
166 	udelay(DIV_ROUND_UP(1000000, eosc1_freq));
167 
168 	/*
169 	 * de-assert active low bhniotri signals,
170 	 * assert active high csrdone and nfrzdrv signal
171 	 */
172 	reg_value = readl(&freeze_controller_base->hioctrl);
173 	reg_value = (reg_value
174 		| SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
175 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK)
176 		& ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
177 	writel(reg_value, &freeze_controller_base->hioctrl);
178 
179 	/*
180 	 * Delay 33 intosc
181 	 * Use worst case which is fatest eosc1=50MHz, delay required
182 	 * is 1/50MHz * 33 = 660ns ~= 1us
183 	 */
184 	udelay(1);
185 
186 	/* de-assert active low plniotri and niotri signals */
187 	reg_cfg_mask
188 		= SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
189 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
190 
191 	setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
192 
193 	/*
194 	 * Note: Delay for 40ns at min
195 	 * de-assert active high frzreg signal
196 	 */
197 	clrbits_le32(&freeze_controller_base->hioctrl,
198 		SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);
199 
200 	/*
201 	 * Note: Delay for 40ns at min
202 	 * de-assert active low enrnsl signal
203 	 */
204 	setbits_le32(&freeze_controller_base->hioctrl,
205 		SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);
206 
207 	/* Set global flag to indicate channel is thawed */
208 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
209 }
210