GNU Linux-libre 6.7.9-gnu
[releases.git] / arch / arm / mach-socfpga / socfpga.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2012-2015 Altera Corporation
4  */
5 #include <linux/irqchip.h>
6 #include <linux/of.h>
7 #include <linux/of_address.h>
8 #include <linux/reboot.h>
9 #include <linux/reset/socfpga.h>
10
11 #include <asm/mach/arch.h>
12 #include <asm/mach/map.h>
13 #include <asm/cacheflush.h>
14
15 #include "core.h"
16
17 void __iomem *sys_manager_base_addr;
18 void __iomem *rst_manager_base_addr;
19 void __iomem *sdr_ctl_base_addr;
20 unsigned long socfpga_cpu1start_addr;
21
22 static void __init socfpga_sysmgr_init(void)
23 {
24         struct device_node *np;
25
26         np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
27
28         if (of_property_read_u32(np, "cpu1-start-addr",
29                         (u32 *) &socfpga_cpu1start_addr))
30                 pr_err("SMP: Need cpu1-start-addr in device tree.\n");
31
32         /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */
33         smp_wmb();
34         sync_cache_w(&socfpga_cpu1start_addr);
35
36         sys_manager_base_addr = of_iomap(np, 0);
37
38         np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
39         rst_manager_base_addr = of_iomap(np, 0);
40
41         np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl");
42         sdr_ctl_base_addr = of_iomap(np, 0);
43 }
44
45 static void __init socfpga_init_irq(void)
46 {
47         irqchip_init();
48         socfpga_sysmgr_init();
49         if (IS_ENABLED(CONFIG_EDAC_ALTERA_L2C))
50                 socfpga_init_l2_ecc();
51
52         if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
53                 socfpga_init_ocram_ecc();
54         socfpga_reset_init();
55 }
56
57 static void __init socfpga_arria10_init_irq(void)
58 {
59         irqchip_init();
60         socfpga_sysmgr_init();
61         if (IS_ENABLED(CONFIG_EDAC_ALTERA_L2C))
62                 socfpga_init_arria10_l2_ecc();
63         if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
64                 socfpga_init_arria10_ocram_ecc();
65         socfpga_reset_init();
66 }
67
68 static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
69 {
70         u32 temp;
71
72         temp = readl(rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
73
74         if (mode == REBOOT_WARM)
75                 temp |= RSTMGR_CTRL_SWWARMRSTREQ;
76         else
77                 temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
78         writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
79 }
80
81 static void socfpga_arria10_restart(enum reboot_mode mode, const char *cmd)
82 {
83         u32 temp;
84
85         temp = readl(rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
86
87         if (mode == REBOOT_WARM)
88                 temp |= RSTMGR_CTRL_SWWARMRSTREQ;
89         else
90                 temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
91         writel(temp, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
92 }
93
94 static const char *altera_dt_match[] = {
95         "altr,socfpga",
96         NULL
97 };
98
99 DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA")
100         .l2c_aux_val    = 0,
101         .l2c_aux_mask   = ~0,
102         .init_irq       = socfpga_init_irq,
103         .restart        = socfpga_cyclone5_restart,
104         .dt_compat      = altera_dt_match,
105 MACHINE_END
106
107 static const char *altera_a10_dt_match[] = {
108         "altr,socfpga-arria10",
109         NULL
110 };
111
112 DT_MACHINE_START(SOCFPGA_A10, "Altera SOCFPGA Arria10")
113         .l2c_aux_val    = 0,
114         .l2c_aux_mask   = ~0,
115         .init_irq       = socfpga_arria10_init_irq,
116         .restart        = socfpga_arria10_restart,
117         .dt_compat      = altera_a10_dt_match,
118 MACHINE_END