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