d48aeec3742614490beaa7ca5b1cdf784840bed1
[oweals/u-boot.git] / arch / arm / mach-socfpga / freeze_controller.c
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 }