]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-socfpga/reset_manager_arria10.c
Merge branch 'master' of git://git.denx.de/u-boot-socfpga
[u-boot] / arch / arm / mach-socfpga / reset_manager_arria10.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016-2017 Intel Corporation
4  */
5
6 #include <asm/io.h>
7 #include <asm/arch/fpga_manager.h>
8 #include <asm/arch/misc.h>
9 #include <asm/arch/reset_manager.h>
10 #include <asm/arch/system_manager.h>
11 #include <common.h>
12 #include <errno.h>
13 #include <fdtdec.h>
14 #include <wait_bit.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 static const struct socfpga_reset_manager *reset_manager_base =
19                 (void *)SOCFPGA_RSTMGR_ADDRESS;
20 static const struct socfpga_system_manager *sysmgr_regs =
21                 (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
22
23 #define ECC_MASK (ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK | \
24         ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK | \
25         ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK | \
26         ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK | \
27         ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK | \
28         ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK)
29
30 void socfpga_reset_uart(int assert)
31 {
32         unsigned int com_port;
33
34         com_port = uart_com_port(gd->fdt_blob);
35
36         if (com_port == SOCFPGA_UART1_ADDRESS)
37                 socfpga_per_reset(SOCFPGA_RESET(UART1), assert);
38         else if (com_port == SOCFPGA_UART0_ADDRESS)
39                 socfpga_per_reset(SOCFPGA_RESET(UART0), assert);
40 }
41
42 static const u32 per0fpgamasks[] = {
43         ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK |
44         ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK,
45         ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK |
46         ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK,
47         ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK |
48         ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK,
49         0, /* i2c0 per1mod */
50         0, /* i2c1 per1mod */
51         0, /* i2c0_emac */
52         0, /* i2c1_emac */
53         0, /* i2c2_emac */
54         ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK |
55         ALT_RSTMGR_PER0MODRST_NAND_SET_MSK,
56         ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK |
57         ALT_RSTMGR_PER0MODRST_QSPI_SET_MSK,
58         ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK |
59         ALT_RSTMGR_PER0MODRST_SDMMC_SET_MSK,
60         ALT_RSTMGR_PER0MODRST_SPIM0_SET_MSK,
61         ALT_RSTMGR_PER0MODRST_SPIM1_SET_MSK,
62         ALT_RSTMGR_PER0MODRST_SPIS0_SET_MSK,
63         ALT_RSTMGR_PER0MODRST_SPIS1_SET_MSK,
64         0, /* uart0 per1mod */
65         0, /* uart1 per1mod */
66 };
67
68 static const u32 per1fpgamasks[] = {
69         0, /* emac0 per0mod */
70         0, /* emac1 per0mod */
71         0, /* emac2 per0mod */
72         ALT_RSTMGR_PER1MODRST_I2C0_SET_MSK,
73         ALT_RSTMGR_PER1MODRST_I2C1_SET_MSK,
74         ALT_RSTMGR_PER1MODRST_I2C2_SET_MSK, /* i2c0_emac */
75         ALT_RSTMGR_PER1MODRST_I2C3_SET_MSK, /* i2c1_emac */
76         ALT_RSTMGR_PER1MODRST_I2C4_SET_MSK, /* i2c2_emac */
77         0, /* nand per0mod */
78         0, /* qspi per0mod */
79         0, /* sdmmc per0mod */
80         0, /* spim0 per0mod */
81         0, /* spim1 per0mod */
82         0, /* spis0 per0mod */
83         0, /* spis1 per0mod */
84         ALT_RSTMGR_PER1MODRST_UART0_SET_MSK,
85         ALT_RSTMGR_PER1MODRST_UART1_SET_MSK,
86 };
87
88 struct bridge_cfg {
89         int compat_id;
90         u32  mask_noc;
91         u32  mask_rstmgr;
92 };
93
94 static const struct bridge_cfg bridge_cfg_tbl[] = {
95         {
96                 COMPAT_ALTERA_SOCFPGA_H2F_BRG,
97                 ALT_SYSMGR_NOC_H2F_SET_MSK,
98                 ALT_RSTMGR_BRGMODRST_H2F_SET_MSK,
99         },
100         {
101                 COMPAT_ALTERA_SOCFPGA_LWH2F_BRG,
102                 ALT_SYSMGR_NOC_LWH2F_SET_MSK,
103                 ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK,
104         },
105         {
106                 COMPAT_ALTERA_SOCFPGA_F2H_BRG,
107                 ALT_SYSMGR_NOC_F2H_SET_MSK,
108                 ALT_RSTMGR_BRGMODRST_F2H_SET_MSK,
109         },
110         {
111                 COMPAT_ALTERA_SOCFPGA_F2SDR0,
112                 ALT_SYSMGR_NOC_F2SDR0_SET_MSK,
113                 ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK,
114         },
115         {
116                 COMPAT_ALTERA_SOCFPGA_F2SDR1,
117                 ALT_SYSMGR_NOC_F2SDR1_SET_MSK,
118                 ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK,
119         },
120         {
121                 COMPAT_ALTERA_SOCFPGA_F2SDR2,
122                 ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
123                 ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK,
124         },
125 };
126
127 /* Disable the watchdog (toggle reset to watchdog) */
128 void socfpga_watchdog_disable(void)
129 {
130         /* assert reset for watchdog */
131         setbits_le32(&reset_manager_base->per1modrst,
132                      ALT_RSTMGR_PER1MODRST_WD0_SET_MSK);
133 }
134
135 /* Release NOC ddr scheduler from reset */
136 void socfpga_reset_deassert_noc_ddr_scheduler(void)
137 {
138         clrbits_le32(&reset_manager_base->brgmodrst,
139                      ALT_RSTMGR_BRGMODRST_DDRSCH_SET_MSK);
140 }
141
142 /* Check whether Watchdog in reset state? */
143 int socfpga_is_wdt_in_reset(void)
144 {
145         u32 val;
146
147         val = readl(&reset_manager_base->per1modrst);
148         val &= ALT_RSTMGR_PER1MODRST_WD0_SET_MSK;
149
150         /* return 0x1 if watchdog in reset */
151         return val;
152 }
153
154 /* emacbase: base address of emac to enable/disable reset
155  * state: 0 - disable reset, !0 - enable reset
156  */
157 void socfpga_emac_manage_reset(ulong emacbase, u32 state)
158 {
159         ulong eccmask;
160         ulong emacmask;
161
162         switch (emacbase) {
163         case SOCFPGA_EMAC0_ADDRESS:
164                 eccmask = ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK;
165                 emacmask = ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK;
166                 break;
167         case SOCFPGA_EMAC1_ADDRESS:
168                 eccmask = ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK;
169                 emacmask = ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK;
170                 break;
171         case SOCFPGA_EMAC2_ADDRESS:
172                 eccmask = ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK;
173                 emacmask = ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK;
174                 break;
175         default:
176                 pr_err("emac base address unexpected! %lx", emacbase);
177                 hang();
178                 break;
179         }
180
181         if (state) {
182                 /* Enable ECC OCP first */
183                 setbits_le32(&reset_manager_base->per0modrst, eccmask);
184                 setbits_le32(&reset_manager_base->per0modrst, emacmask);
185         } else {
186                 /* Disable ECC OCP first */
187                 clrbits_le32(&reset_manager_base->per0modrst, emacmask);
188                 clrbits_le32(&reset_manager_base->per0modrst, eccmask);
189         }
190 }
191
192 static int get_bridge_init_val(const void *blob, int compat_id)
193 {
194         int node;
195
196         node = fdtdec_next_compatible(blob, 0, compat_id);
197         if (node < 0)
198                 return 0;
199
200         return fdtdec_get_uint(blob, node, "init-val", 0);
201 }
202
203 /* Enable bridges (hps2fpga, lwhps2fpga, fpga2hps, fpga2sdram) per handoff */
204 int socfpga_reset_deassert_bridges_handoff(void)
205 {
206         u32 mask_noc = 0, mask_rstmgr = 0;
207         int i;
208
209         for (i = 0; i < ARRAY_SIZE(bridge_cfg_tbl); i++) {
210                 if (get_bridge_init_val(gd->fdt_blob,
211                                         bridge_cfg_tbl[i].compat_id)) {
212                         mask_noc |= bridge_cfg_tbl[i].mask_noc;
213                         mask_rstmgr |= bridge_cfg_tbl[i].mask_rstmgr;
214                 }
215         }
216
217         /* clear idle request to all bridges */
218         setbits_le32(&sysmgr_regs->noc_idlereq_clr, mask_noc);
219
220         /* Release bridges from reset state per handoff value */
221         clrbits_le32(&reset_manager_base->brgmodrst, mask_rstmgr);
222
223         /* Poll until all idleack to 0, timeout at 1000ms */
224         return wait_for_bit_le32(&sysmgr_regs->noc_idleack, mask_noc,
225                                  false, 1000, false);
226 }
227
228 void socfpga_reset_assert_fpga_connected_peripherals(void)
229 {
230         u32 mask0 = 0;
231         u32 mask1 = 0;
232         u32 fpga_pinux_addr = SOCFPGA_PINMUX_FPGA_INTERFACE_ADDRESS;
233         int i;
234
235         for (i = 0; i < ARRAY_SIZE(per1fpgamasks); i++) {
236                 if (readl(fpga_pinux_addr)) {
237                         mask0 |= per0fpgamasks[i];
238                         mask1 |= per1fpgamasks[i];
239                 }
240                 fpga_pinux_addr += sizeof(u32);
241         }
242
243         setbits_le32(&reset_manager_base->per0modrst, mask0 & ECC_MASK);
244         setbits_le32(&reset_manager_base->per1modrst, mask1);
245         setbits_le32(&reset_manager_base->per0modrst, mask0);
246 }
247
248 /* Release L4 OSC1 Watchdog Timer 0 from reset through reset manager */
249 void socfpga_reset_deassert_osc1wd0(void)
250 {
251         clrbits_le32(&reset_manager_base->per1modrst,
252                      ALT_RSTMGR_PER1MODRST_WD0_SET_MSK);
253 }
254
255 /*
256  * Assert or de-assert SoCFPGA reset manager reset.
257  */
258 void socfpga_per_reset(u32 reset, int set)
259 {
260         const u32 *reg;
261         u32 rstmgr_bank = RSTMGR_BANK(reset);
262
263         switch (rstmgr_bank) {
264         case 0:
265                 reg = &reset_manager_base->mpumodrst;
266                 break;
267         case 1:
268                 reg = &reset_manager_base->per0modrst;
269                 break;
270         case 2:
271                 reg = &reset_manager_base->per1modrst;
272                 break;
273         case 3:
274                 reg = &reset_manager_base->brgmodrst;
275                 break;
276         case 4:
277                 reg = &reset_manager_base->sysmodrst;
278                 break;
279
280         default:
281                 return;
282         }
283
284         if (set)
285                 setbits_le32(reg, 1 << RSTMGR_RESET(reset));
286         else
287                 clrbits_le32(reg, 1 << RSTMGR_RESET(reset));
288 }
289
290 /*
291  * Assert reset on every peripheral but L4WD0.
292  * Watchdog must be kept intact to prevent glitches
293  * and/or hangs.
294  * For the Arria10, we disable all the peripherals except L4 watchdog0,
295  * L4 Timer 0, and ECC.
296  */
297 void socfpga_per_reset_all(void)
298 {
299         const u32 l4wd0 = (1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)) |
300                           (1 << RSTMGR_RESET(SOCFPGA_RESET(L4SYSTIMER0))));
301         unsigned mask_ecc_ocp =
302                 ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK |
303                 ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK |
304                 ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK |
305                 ALT_RSTMGR_PER0MODRST_USBECC0_SET_MSK |
306                 ALT_RSTMGR_PER0MODRST_USBECC1_SET_MSK |
307                 ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK |
308                 ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK |
309                 ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK;
310
311         /* disable all components except ECC_OCP, L4 Timer0 and L4 WD0 */
312         writel(~l4wd0, &reset_manager_base->per1modrst);
313         setbits_le32(&reset_manager_base->per0modrst, ~mask_ecc_ocp);
314
315         /* Finally disable the ECC_OCP */
316         setbits_le32(&reset_manager_base->per0modrst, mask_ecc_ocp);
317 }
318
319 int socfpga_bridges_reset(void)
320 {
321         int ret;
322
323         /* Disable all the bridges (hps2fpga, lwhps2fpga, fpga2hps,
324            fpga2sdram) */
325         /* set idle request to all bridges */
326         writel(ALT_SYSMGR_NOC_H2F_SET_MSK |
327                 ALT_SYSMGR_NOC_LWH2F_SET_MSK |
328                 ALT_SYSMGR_NOC_F2H_SET_MSK |
329                 ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
330                 ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
331                 ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
332                 &sysmgr_regs->noc_idlereq_set);
333
334         /* Enable the NOC timeout */
335         writel(ALT_SYSMGR_NOC_TMO_EN_SET_MSK, &sysmgr_regs->noc_timeout);
336
337         /* Poll until all idleack to 1 */
338         ret = wait_for_bit_le32(&sysmgr_regs->noc_idleack,
339                                 ALT_SYSMGR_NOC_H2F_SET_MSK |
340                                 ALT_SYSMGR_NOC_LWH2F_SET_MSK |
341                                 ALT_SYSMGR_NOC_F2H_SET_MSK |
342                                 ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
343                                 ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
344                                 ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
345                                 true, 10000, false);
346         if (ret)
347                 return ret;
348
349         /* Poll until all idlestatus to 1 */
350         ret = wait_for_bit_le32(&sysmgr_regs->noc_idlestatus,
351                                 ALT_SYSMGR_NOC_H2F_SET_MSK |
352                                 ALT_SYSMGR_NOC_LWH2F_SET_MSK |
353                                 ALT_SYSMGR_NOC_F2H_SET_MSK |
354                                 ALT_SYSMGR_NOC_F2SDR0_SET_MSK |
355                                 ALT_SYSMGR_NOC_F2SDR1_SET_MSK |
356                                 ALT_SYSMGR_NOC_F2SDR2_SET_MSK,
357                                 true, 10000, false);
358         if (ret)
359                 return ret;
360
361         /* Put all bridges (except NOR DDR scheduler) into reset state */
362         setbits_le32(&reset_manager_base->brgmodrst,
363                      (ALT_RSTMGR_BRGMODRST_H2F_SET_MSK |
364                      ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK |
365                      ALT_RSTMGR_BRGMODRST_F2H_SET_MSK |
366                      ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK |
367                      ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK |
368                      ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK));
369
370         /* Disable NOC timeout */
371         writel(0, &sysmgr_regs->noc_timeout);
372
373         return 0;
374 }