1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2013 Altera Corporation <www.altera.com>
9 #include <asm/arch/clock_manager.h>
10 #include <asm/arch/freeze_controller.h>
11 #include <linux/errno.h>
13 static const struct socfpga_freeze_controller *freeze_controller_base =
14 (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
17 * Default state from cold reset is FREEZE_ALL; the global
18 * flag is set to TRUE to indicate the IO banks are frozen
20 static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
21 = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
22 FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};
25 void sys_mgr_frzctrl_freeze_req(void)
27 u32 ioctrl_reg_offset;
32 /* select software FSM */
33 writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src);
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);
41 * Assert active low enrnsl, plniotri
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);
51 * Note: Delay for 20ns at min
52 * Assert active low bhniotri signal and de-assert
56 = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
57 | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
58 clrbits_le32(ioctrl_reg_offset, reg_cfg_mask);
60 /* Set global flag to indicate channel is frozen */
61 frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
64 /* Freeze channel 3 */
66 * Assert active low enrnsl, plniotri and
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);
76 * assert active low bhniotri & nfrzdrv signals,
77 * de-assert active high csrdone and assert
78 * active high frzreg and nfrzdrv signals
80 reg_value = readl(&freeze_controller_base->hioctrl);
82 = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
83 | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
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);
91 * assert active high reinit signal and de-assert
92 * active high pllbiasen signals
94 reg_value = readl(&freeze_controller_base->hioctrl);
97 ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
98 | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
99 writel(reg_value, &freeze_controller_base->hioctrl);
101 /* Set global flag to indicate channel is frozen */
102 frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
105 /* Unfreeze/Thaw HPS IOs */
106 void sys_mgr_frzctrl_thaw_req(void)
108 u32 ioctrl_reg_offset;
112 unsigned long eosc1_freq;
114 /* select software FSM */
115 writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src);
117 /* Thaw channel 0 to 2 */
118 for (channel_id = 0; channel_id <= 2; channel_id++) {
120 = (u32)(&freeze_controller_base->vioctrl + channel_id);
123 * Assert active low bhniotri signal and
124 * de-assert active high csrdone
127 = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
128 | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
129 setbits_le32(ioctrl_reg_offset, reg_cfg_mask);
132 * Note: Delay for 20ns at min
133 * de-assert active low plniotri and niotri signals
136 = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
137 | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
138 setbits_le32(ioctrl_reg_offset, reg_cfg_mask);
141 * Note: Delay for 20ns at min
142 * de-assert active low enrnsl signal
144 setbits_le32(ioctrl_reg_offset,
145 SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);
147 /* Set global flag to indicate channel is thawed */
148 frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
152 /* de-assert active high reinit signal */
153 clrbits_le32(&freeze_controller_base->hioctrl,
154 SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
157 * Note: Delay for 40ns at min
158 * assert active high pllbiasen signals
160 setbits_le32(&freeze_controller_base->hioctrl,
161 SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
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));
168 * de-assert active low bhniotri signals,
169 * assert active high csrdone and nfrzdrv signal
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);
180 * Use worst case which is fatest eosc1=50MHz, delay required
181 * is 1/50MHz * 33 = 660ns ~= 1us
185 /* de-assert active low plniotri and niotri signals */
187 = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
188 | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
190 setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
193 * Note: Delay for 40ns at min
194 * de-assert active high frzreg signal
196 clrbits_le32(&freeze_controller_base->hioctrl,
197 SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);
200 * Note: Delay for 40ns at min
201 * de-assert active low enrnsl signal
203 setbits_le32(&freeze_controller_base->hioctrl,
204 SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);
206 /* Set global flag to indicate channel is thawed */
207 frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;