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