af8f2c0873104b96eb9c70f8949b7fbe74e3c997
[platform/kernel/u-boot.git] / arch / arm / mach-socfpga / reset_manager_s10.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
4  *
5  */
6
7 #include <common.h>
8 #include <hang.h>
9 #include <asm/io.h>
10 #include <asm/arch/reset_manager.h>
11 #include <asm/arch/smc_api.h>
12 #include <asm/arch/system_manager.h>
13 #include <dt-bindings/reset/altr,rst-mgr-s10.h>
14 #include <linux/iopoll.h>
15 #include <linux/intel-smc.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 /* Assert or de-assert SoCFPGA reset manager reset. */
20 void socfpga_per_reset(u32 reset, int set)
21 {
22         unsigned long reg;
23
24         if (RSTMGR_BANK(reset) == 0)
25                 reg = RSTMGR_SOC64_MPUMODRST;
26         else if (RSTMGR_BANK(reset) == 1)
27                 reg = RSTMGR_SOC64_PER0MODRST;
28         else if (RSTMGR_BANK(reset) == 2)
29                 reg = RSTMGR_SOC64_PER1MODRST;
30         else if (RSTMGR_BANK(reset) == 3)
31                 reg = RSTMGR_SOC64_BRGMODRST;
32         else    /* Invalid reset register, do nothing */
33                 return;
34
35         if (set)
36                 setbits_le32(socfpga_get_rstmgr_addr() + reg,
37                              1 << RSTMGR_RESET(reset));
38         else
39                 clrbits_le32(socfpga_get_rstmgr_addr() + reg,
40                              1 << RSTMGR_RESET(reset));
41 }
42
43 /*
44  * Assert reset on every peripheral but L4WD0.
45  * Watchdog must be kept intact to prevent glitches
46  * and/or hangs.
47  */
48 void socfpga_per_reset_all(void)
49 {
50         const u32 l4wd0 = 1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0));
51
52         /* disable all except OCP and l4wd0. OCP disable later */
53         writel(~(l4wd0 | RSTMGR_PER0MODRST_OCP_MASK),
54                       socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER0MODRST);
55         writel(~l4wd0, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER0MODRST);
56         writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER1MODRST);
57 }
58
59 void socfpga_bridges_reset(int enable)
60 {
61 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
62         u64 arg = enable;
63
64         int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0);
65         if (ret) {
66                 printf("SMC call failed with error %d in %s.\n", ret, __func__);
67                 return;
68         }
69 #else
70         u32 reg;
71
72         if (enable) {
73                 /* clear idle request to all bridges */
74                 setbits_le32(socfpga_get_sysmgr_addr() +
75                              SYSMGR_SOC64_NOC_IDLEREQ_CLR, ~0);
76
77                 /* Release all bridges from reset state */
78                 clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
79                              ~0);
80
81                 /* Poll until all idleack to 0 */
82                 read_poll_timeout(readl, socfpga_get_sysmgr_addr() +
83                                   SYSMGR_SOC64_NOC_IDLEACK, reg, !reg, 1000,
84                                   300000);
85         } else {
86                 /* set idle request to all bridges */
87                 writel(~0,
88                        socfpga_get_sysmgr_addr() +
89                        SYSMGR_SOC64_NOC_IDLEREQ_SET);
90
91                 /* Enable the NOC timeout */
92                 writel(1, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
93
94                 /* Poll until all idleack to 1 */
95                 read_poll_timeout(readl, socfpga_get_sysmgr_addr() +
96                                   SYSMGR_SOC64_NOC_IDLEACK, reg,
97                                   reg == (SYSMGR_NOC_H2F_MSK |
98                                           SYSMGR_NOC_LWH2F_MSK),
99                                   1000, 300000);
100
101                 /* Poll until all idlestatus to 1 */
102                 read_poll_timeout(readl, socfpga_get_sysmgr_addr() +
103                                   SYSMGR_SOC64_NOC_IDLESTATUS, reg,
104                                   reg == (SYSMGR_NOC_H2F_MSK |
105                                           SYSMGR_NOC_LWH2F_MSK),
106                                   1000, 300000);
107
108                 /* Reset all bridges (except NOR DDR scheduler & F2S) */
109                 setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
110                              ~(RSTMGR_BRGMODRST_DDRSCH_MASK |
111                                RSTMGR_BRGMODRST_FPGA2SOC_MASK));
112
113                 /* Disable NOC timeout */
114                 writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
115         }
116 #endif
117 }
118
119 /*
120  * Return non-zero if the CPU has been warm reset
121  */
122 int cpu_has_been_warmreset(void)
123 {
124         return readl(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_STATUS) &
125                         RSTMGR_L4WD_MPU_WARMRESET_MASK;
126 }
127
128 void print_reset_info(void)
129 {
130         bool iswd;
131         int n;
132         u32 stat = cpu_has_been_warmreset();
133
134         printf("Reset state: %s%s", stat ? "Warm " : "Cold",
135                (stat & RSTMGR_STAT_SDMWARMRST) ? "[from SDM] " : "");
136
137         stat &= ~RSTMGR_STAT_SDMWARMRST;
138         if (!stat) {
139                 puts("\n");
140                 return;
141         }
142
143         n = generic_ffs(stat) - 1;
144         iswd = (n >= RSTMGR_STAT_L4WD0RST_BITPOS);
145         printf("(Triggered by %s %d)\n", iswd ? "Watchdog" : "MPU",
146                iswd ? (n - RSTMGR_STAT_L4WD0RST_BITPOS) :
147                (n - RSTMGR_STAT_MPU0RST_BITPOS));
148 }