Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / mach-socfpga / reset_manager_gen5.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/fpga_manager.h>
10 #include <asm/arch/reset_manager.h>
11 #include <asm/arch/system_manager.h>
12 #include <linux/bitops.h>
13
14 /* Assert or de-assert SoCFPGA reset manager reset. */
15 void socfpga_per_reset(u32 reset, int set)
16 {
17         unsigned long reg;
18         u32 rstmgr_bank = RSTMGR_BANK(reset);
19
20         switch (rstmgr_bank) {
21         case 0:
22                 reg = RSTMGR_GEN5_MPUMODRST;
23                 break;
24         case 1:
25                 reg = RSTMGR_GEN5_PERMODRST;
26                 break;
27         case 2:
28                 reg = RSTMGR_GEN5_PER2MODRST;
29                 break;
30         case 3:
31                 reg = RSTMGR_GEN5_BRGMODRST;
32                 break;
33         case 4:
34                 reg = RSTMGR_GEN5_MISCMODRST;
35                 break;
36
37         default:
38                 return;
39         }
40
41         if (set)
42                 setbits_le32(socfpga_get_rstmgr_addr() + reg,
43                              1 << RSTMGR_RESET(reset));
44         else
45                 clrbits_le32(socfpga_get_rstmgr_addr() + reg,
46                              1 << RSTMGR_RESET(reset));
47 }
48
49 /*
50  * Assert reset on every peripheral but L4WD0.
51  * Watchdog must be kept intact to prevent glitches
52  * and/or hangs.
53  */
54 void socfpga_per_reset_all(void)
55 {
56         const u32 l4wd0 = 1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0));
57
58         writel(~l4wd0, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_PERMODRST);
59         writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_PER2MODRST);
60 }
61
62 #define L3REGS_REMAP_LWHPS2FPGA_MASK    0x10
63 #define L3REGS_REMAP_HPS2FPGA_MASK      0x08
64 #define L3REGS_REMAP_OCRAM_MASK         0x01
65
66 void socfpga_bridges_set_handoff_regs(bool h2f, bool lwh2f, bool f2h)
67 {
68         u32 brgmask = 0x0;
69         u32 l3rmask = L3REGS_REMAP_OCRAM_MASK;
70
71         if (h2f)
72                 brgmask |= BIT(0);
73         else
74                 l3rmask |= L3REGS_REMAP_HPS2FPGA_MASK;
75
76         if (lwh2f)
77                 brgmask |= BIT(1);
78         else
79                 l3rmask |= L3REGS_REMAP_LWHPS2FPGA_MASK;
80
81         if (f2h)
82                 brgmask |= BIT(2);
83
84         writel(brgmask,
85                socfpga_get_sysmgr_addr() + SYSMGR_ISWGRP_HANDOFF_OFFSET(0));
86         writel(l3rmask,
87                socfpga_get_sysmgr_addr() + SYSMGR_ISWGRP_HANDOFF_OFFSET(1));
88 }
89
90 void socfpga_bridges_reset(int enable)
91 {
92         const u32 l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK |
93                                 L3REGS_REMAP_HPS2FPGA_MASK |
94                                 L3REGS_REMAP_OCRAM_MASK;
95
96         if (enable) {
97                 /* brdmodrst */
98                 writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
99                 writel(L3REGS_REMAP_OCRAM_MASK, SOCFPGA_L3REGS_ADDRESS);
100         } else {
101                 socfpga_bridges_set_handoff_regs(false, false, false);
102
103                 /* Check signal from FPGA. */
104                 if (!fpgamgr_test_fpga_ready()) {
105                         /* FPGA not ready, do nothing. We allow system to boot
106                          * without FPGA ready. So, return 0 instead of error. */
107                         printf("%s: FPGA not ready, aborting.\n", __func__);
108                         return;
109                 }
110
111                 /* brdmodrst */
112                 writel(0, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
113
114                 /* Remap the bridges into memory map */
115                 writel(l3mask, SOCFPGA_L3REGS_ADDRESS);
116         }
117         return;
118 }