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