aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/edac/socfpga-eccmgr.txt (renamed from Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt)35
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts6
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi83
-rw-r--r--arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts44
-rw-r--r--drivers/acpi/apei/ghes.c16
-rw-r--r--drivers/edac/Kconfig3
-rw-r--r--drivers/edac/altera_edac.c504
-rw-r--r--drivers/edac/altera_edac.h132
-rw-r--r--drivers/edac/ghes_edac.c55
-rw-r--r--drivers/edac/i7core_edac.c2
-rw-r--r--include/acpi/ghes.h7
11 files changed, 817 insertions, 70 deletions
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt b/Documentation/devicetree/bindings/edac/socfpga-eccmgr.txt
index 4a1714f96bab..5626560a6cfd 100644
--- a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt
+++ b/Documentation/devicetree/bindings/edac/socfpga-eccmgr.txt
@@ -231,3 +231,38 @@ Example:
231 <48 IRQ_TYPE_LEVEL_HIGH>; 231 <48 IRQ_TYPE_LEVEL_HIGH>;
232 }; 232 };
233 }; 233 };
234
235Stratix10 SoCFPGA ECC Manager
236The Stratix10 SoC ECC Manager handles the IRQs for each peripheral
237in a shared register similar to the Arria10. However, ECC requires
238access to registers that can only be read from Secure Monitor with
239SMC calls. Therefore the device tree is slightly different.
240
241Required Properties:
242- compatible : Should be "altr,socfpga-s10-ecc-manager"
243- interrupts : Should be single bit error interrupt, then double bit error
244 interrupt.
245- interrupt-controller : boolean indicator that ECC Manager is an interrupt controller
246- #interrupt-cells : must be set to 2.
247
248Subcomponents:
249
250SDRAM ECC
251Required Properties:
252- compatible : Should be "altr,sdram-edac-s10"
253- interrupts : Should be single bit error interrupt, then double bit error
254 interrupt, in this order.
255
256Example:
257
258 eccmgr {
259 compatible = "altr,socfpga-s10-ecc-manager";
260 interrupts = <0 15 4>, <0 95 4>;
261 interrupt-controller;
262 #interrupt-cells = <2>;
263
264 sdramedac {
265 compatible = "altr,sdram-edac-s10";
266 interrupts = <16 4>, <48 4>;
267 };
268 };
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
index 2459d133f1be..f50b19447de6 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
@@ -161,7 +161,7 @@
161 }; 161 };
162 162
163 at24@50 { 163 at24@50 {
164 compatible = "at24,24c01"; 164 compatible = "atmel,24c01";
165 pagesize = <8>; 165 pagesize = <8>;
166 reg = <0x50>; 166 reg = <0x50>;
167 }; 167 };
@@ -213,7 +213,7 @@
213 #size-cells = <0>; 213 #size-cells = <0>;
214 reg = <6>; 214 reg = <6>;
215 eeprom@51 { 215 eeprom@51 {
216 compatible = "at,24c01"; 216 compatible = "atmel,24c01";
217 pagesize = <8>; 217 pagesize = <8>;
218 reg = <0x51>; 218 reg = <0x51>;
219 }; 219 };
@@ -224,7 +224,7 @@
224 #size-cells = <0>; 224 #size-cells = <0>;
225 reg = <7>; 225 reg = <7>;
226 eeprom@51 { 226 eeprom@51 {
227 compatible = "at,24c01"; 227 compatible = "atmel,24c01";
228 pagesize = <8>; 228 pagesize = <8>;
229 reg = <0x51>; 229 reg = <0x51>;
230 }; 230 };
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
index c89d0c307f8d..e6b059378dc0 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -17,6 +17,7 @@
17/dts-v1/; 17/dts-v1/;
18#include <dt-bindings/reset/altr,rst-mgr-s10.h> 18#include <dt-bindings/reset/altr,rst-mgr-s10.h>
19#include <dt-bindings/gpio/gpio.h> 19#include <dt-bindings/gpio/gpio.h>
20#include <dt-bindings/clock/stratix10-clock.h>
20 21
21/ { 22/ {
22 compatible = "altr,socfpga-stratix10"; 23 compatible = "altr,socfpga-stratix10";
@@ -92,9 +93,32 @@
92 interrupt-parent = <&intc>; 93 interrupt-parent = <&intc>;
93 ranges = <0 0 0 0xffffffff>; 94 ranges = <0 0 0 0xffffffff>;
94 95
95 clkmgr@ffd1000 { 96 clkmgr: clock-controller@ffd10000 {
96 compatible = "altr,clk-mgr"; 97 compatible = "intel,stratix10-clkmgr";
97 reg = <0xffd10000 0x1000>; 98 reg = <0xffd10000 0x1000>;
99 #clock-cells = <1>;
100 };
101
102 clocks {
103 cb_intosc_hs_div2_clk: cb-intosc-hs-div2-clk {
104 #clock-cells = <0>;
105 compatible = "fixed-clock";
106 };
107
108 cb_intosc_ls_clk: cb-intosc-ls-clk {
109 #clock-cells = <0>;
110 compatible = "fixed-clock";
111 };
112
113 f2s_free_clk: f2s-free-clk {
114 #clock-cells = <0>;
115 compatible = "fixed-clock";
116 };
117
118 osc1: osc1 {
119 #clock-cells = <0>;
120 compatible = "fixed-clock";
121 };
98 }; 122 };
99 123
100 gmac0: ethernet@ff800000 { 124 gmac0: ethernet@ff800000 {
@@ -105,6 +129,8 @@
105 mac-address = [00 00 00 00 00 00]; 129 mac-address = [00 00 00 00 00 00];
106 resets = <&rst EMAC0_RESET>; 130 resets = <&rst EMAC0_RESET>;
107 reset-names = "stmmaceth"; 131 reset-names = "stmmaceth";
132 clocks = <&clkmgr STRATIX10_EMAC0_CLK>;
133 clock-names = "stmmaceth";
108 status = "disabled"; 134 status = "disabled";
109 }; 135 };
110 136
@@ -116,6 +142,8 @@
116 mac-address = [00 00 00 00 00 00]; 142 mac-address = [00 00 00 00 00 00];
117 resets = <&rst EMAC1_RESET>; 143 resets = <&rst EMAC1_RESET>;
118 reset-names = "stmmaceth"; 144 reset-names = "stmmaceth";
145 clocks = <&clkmgr STRATIX10_EMAC1_CLK>;
146 clock-names = "stmmaceth";
119 status = "disabled"; 147 status = "disabled";
120 }; 148 };
121 149
@@ -127,6 +155,8 @@
127 mac-address = [00 00 00 00 00 00]; 155 mac-address = [00 00 00 00 00 00];
128 resets = <&rst EMAC2_RESET>; 156 resets = <&rst EMAC2_RESET>;
129 reset-names = "stmmaceth"; 157 reset-names = "stmmaceth";
158 clocks = <&clkmgr STRATIX10_EMAC2_CLK>;
159 clock-names = "stmmaceth";
130 status = "disabled"; 160 status = "disabled";
131 }; 161 };
132 162
@@ -177,6 +207,7 @@
177 reg = <0xffc02800 0x100>; 207 reg = <0xffc02800 0x100>;
178 interrupts = <0 103 4>; 208 interrupts = <0 103 4>;
179 resets = <&rst I2C0_RESET>; 209 resets = <&rst I2C0_RESET>;
210 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
180 status = "disabled"; 211 status = "disabled";
181 }; 212 };
182 213
@@ -187,6 +218,7 @@
187 reg = <0xffc02900 0x100>; 218 reg = <0xffc02900 0x100>;
188 interrupts = <0 104 4>; 219 interrupts = <0 104 4>;
189 resets = <&rst I2C1_RESET>; 220 resets = <&rst I2C1_RESET>;
221 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
190 status = "disabled"; 222 status = "disabled";
191 }; 223 };
192 224
@@ -197,6 +229,7 @@
197 reg = <0xffc02a00 0x100>; 229 reg = <0xffc02a00 0x100>;
198 interrupts = <0 105 4>; 230 interrupts = <0 105 4>;
199 resets = <&rst I2C2_RESET>; 231 resets = <&rst I2C2_RESET>;
232 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
200 status = "disabled"; 233 status = "disabled";
201 }; 234 };
202 235
@@ -207,6 +240,7 @@
207 reg = <0xffc02b00 0x100>; 240 reg = <0xffc02b00 0x100>;
208 interrupts = <0 106 4>; 241 interrupts = <0 106 4>;
209 resets = <&rst I2C3_RESET>; 242 resets = <&rst I2C3_RESET>;
243 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
210 status = "disabled"; 244 status = "disabled";
211 }; 245 };
212 246
@@ -217,6 +251,7 @@
217 reg = <0xffc02c00 0x100>; 251 reg = <0xffc02c00 0x100>;
218 interrupts = <0 107 4>; 252 interrupts = <0 107 4>;
219 resets = <&rst I2C4_RESET>; 253 resets = <&rst I2C4_RESET>;
254 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
220 status = "disabled"; 255 status = "disabled";
221 }; 256 };
222 257
@@ -229,6 +264,9 @@
229 fifo-depth = <0x400>; 264 fifo-depth = <0x400>;
230 resets = <&rst SDMMC_RESET>; 265 resets = <&rst SDMMC_RESET>;
231 reset-names = "reset"; 266 reset-names = "reset";
267 clocks = <&clkmgr STRATIX10_L4_MP_CLK>,
268 <&clkmgr STRATIX10_SDMMC_CLK>;
269 clock-names = "biu", "ciu";
232 status = "disabled"; 270 status = "disabled";
233 }; 271 };
234 272
@@ -237,6 +275,25 @@
237 reg = <0xffe00000 0x100000>; 275 reg = <0xffe00000 0x100000>;
238 }; 276 };
239 277
278 pdma: pdma@ffda0000 {
279 compatible = "arm,pl330", "arm,primecell";
280 reg = <0xffda0000 0x1000>;
281 interrupts = <0 81 4>,
282 <0 82 4>,
283 <0 83 4>,
284 <0 84 4>,
285 <0 85 4>,
286 <0 86 4>,
287 <0 87 4>,
288 <0 88 4>,
289 <0 89 4>;
290 #dma-cells = <1>;
291 #dma-channels = <8>;
292 #dma-requests = <32>;
293 clocks = <&clkmgr STRATIX10_L4_MAIN_CLK>;
294 clock-names = "apb_pclk";
295 };
296
240 rst: rstmgr@ffd11000 { 297 rst: rstmgr@ffd11000 {
241 #reset-cells = <1>; 298 #reset-cells = <1>;
242 compatible = "altr,rst-mgr"; 299 compatible = "altr,rst-mgr";
@@ -288,24 +345,32 @@
288 compatible = "snps,dw-apb-timer"; 345 compatible = "snps,dw-apb-timer";
289 interrupts = <0 113 4>; 346 interrupts = <0 113 4>;
290 reg = <0xffc03000 0x100>; 347 reg = <0xffc03000 0x100>;
348 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
349 clock-names = "timer";
291 }; 350 };
292 351
293 timer1: timer1@ffc03100 { 352 timer1: timer1@ffc03100 {
294 compatible = "snps,dw-apb-timer"; 353 compatible = "snps,dw-apb-timer";
295 interrupts = <0 114 4>; 354 interrupts = <0 114 4>;
296 reg = <0xffc03100 0x100>; 355 reg = <0xffc03100 0x100>;
356 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
357 clock-names = "timer";
297 }; 358 };
298 359
299 timer2: timer2@ffd00000 { 360 timer2: timer2@ffd00000 {
300 compatible = "snps,dw-apb-timer"; 361 compatible = "snps,dw-apb-timer";
301 interrupts = <0 115 4>; 362 interrupts = <0 115 4>;
302 reg = <0xffd00000 0x100>; 363 reg = <0xffd00000 0x100>;
364 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
365 clock-names = "timer";
303 }; 366 };
304 367
305 timer3: timer3@ffd00100 { 368 timer3: timer3@ffd00100 {
306 compatible = "snps,dw-apb-timer"; 369 compatible = "snps,dw-apb-timer";
307 interrupts = <0 116 4>; 370 interrupts = <0 116 4>;
308 reg = <0xffd00100 0x100>; 371 reg = <0xffd00100 0x100>;
372 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
373 clock-names = "timer";
309 }; 374 };
310 375
311 uart0: serial0@ffc02000 { 376 uart0: serial0@ffc02000 {
@@ -315,6 +380,7 @@
315 reg-shift = <2>; 380 reg-shift = <2>;
316 reg-io-width = <4>; 381 reg-io-width = <4>;
317 resets = <&rst UART0_RESET>; 382 resets = <&rst UART0_RESET>;
383 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
318 status = "disabled"; 384 status = "disabled";
319 }; 385 };
320 386
@@ -325,6 +391,7 @@
325 reg-shift = <2>; 391 reg-shift = <2>;
326 reg-io-width = <4>; 392 reg-io-width = <4>;
327 resets = <&rst UART1_RESET>; 393 resets = <&rst UART1_RESET>;
394 clocks = <&clkmgr STRATIX10_L4_SP_CLK>;
328 status = "disabled"; 395 status = "disabled";
329 }; 396 };
330 397
@@ -387,5 +454,17 @@
387 resets = <&rst WATCHDOG3_RESET>; 454 resets = <&rst WATCHDOG3_RESET>;
388 status = "disabled"; 455 status = "disabled";
389 }; 456 };
457
458 eccmgr {
459 compatible = "altr,socfpga-s10-ecc-manager";
460 interrupts = <0 15 4>, <0 95 4>;
461 interrupt-controller;
462 #interrupt-cells = <2>;
463
464 sdramedac {
465 compatible = "altr,sdram-edac-s10";
466 interrupts = <16 4>, <48 4>;
467 };
468 };
390 }; 469 };
391}; 470};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index eaf13fe29287..f9b1ef12db48 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -50,6 +50,21 @@
50 /* We expect the bootloader to fill in the reg */ 50 /* We expect the bootloader to fill in the reg */
51 reg = <0 0 0 0>; 51 reg = <0 0 0 0>;
52 }; 52 };
53
54 ref_033v: 033-v-ref {
55 compatible = "regulator-fixed";
56 regulator-name = "0.33V";
57 regulator-min-microvolt = <330000>;
58 regulator-max-microvolt = <330000>;
59 };
60
61 soc {
62 clocks {
63 osc1 {
64 clock-frequency = <25000000>;
65 };
66 };
67 };
53}; 68};
54 69
55&gpio1 { 70&gpio1 {
@@ -79,7 +94,7 @@
79 rxd2-skew-ps = <420>; /* 0ps */ 94 rxd2-skew-ps = <420>; /* 0ps */
80 rxd3-skew-ps = <420>; /* 0ps */ 95 rxd3-skew-ps = <420>; /* 0ps */
81 txen-skew-ps = <0>; /* -420ps */ 96 txen-skew-ps = <0>; /* -420ps */
82 txc-skew-ps = <1860>; /* 960ps */ 97 txc-skew-ps = <900>; /* 0ps */
83 rxdv-skew-ps = <420>; /* 0ps */ 98 rxdv-skew-ps = <420>; /* 0ps */
84 rxc-skew-ps = <1680>; /* 780ps */ 99 rxc-skew-ps = <1680>; /* 780ps */
85 }; 100 };
@@ -105,3 +120,30 @@
105&watchdog0 { 120&watchdog0 {
106 status = "okay"; 121 status = "okay";
107}; 122};
123
124&i2c1 {
125 status = "okay";
126 clock-frequency = <100000>;
127
128 adc@14 {
129 compatible = "lltc,ltc2497";
130 reg = <0x14>;
131 vref-supply = <&ref_033v>;
132 };
133
134 temp@4c {
135 compatible = "maxim,max1619";
136 reg = <0x4c>;
137 };
138
139 eeprom@51 {
140 compatible = "atmel,24c32";
141 reg = <0x51>;
142 pagesize = <32>;
143 };
144
145 rtc@68 {
146 compatible = "dallas,ds1339";
147 reg = <0x68>;
148 };
149};
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe919555..02c6fd9caff7 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -481,7 +481,7 @@ static void ghes_do_proc(struct ghes *ghes,
481 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { 481 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
482 struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); 482 struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
483 483
484 ghes_edac_report_mem_error(ghes, sev, mem_err); 484 ghes_edac_report_mem_error(sev, mem_err);
485 485
486 arch_apei_report_mem_error(sev, mem_err); 486 arch_apei_report_mem_error(sev, mem_err);
487 ghes_handle_memory_failure(gdata, sev); 487 ghes_handle_memory_failure(gdata, sev);
@@ -1087,10 +1087,6 @@ static int ghes_probe(struct platform_device *ghes_dev)
1087 goto err; 1087 goto err;
1088 } 1088 }
1089 1089
1090 rc = ghes_edac_register(ghes, &ghes_dev->dev);
1091 if (rc < 0)
1092 goto err;
1093
1094 switch (generic->notify.type) { 1090 switch (generic->notify.type) {
1095 case ACPI_HEST_NOTIFY_POLLED: 1091 case ACPI_HEST_NOTIFY_POLLED:
1096 timer_setup(&ghes->timer, ghes_poll_func, TIMER_DEFERRABLE); 1092 timer_setup(&ghes->timer, ghes_poll_func, TIMER_DEFERRABLE);
@@ -1102,14 +1098,14 @@ static int ghes_probe(struct platform_device *ghes_dev)
1102 if (rc) { 1098 if (rc) {
1103 pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n", 1099 pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n",
1104 generic->header.source_id); 1100 generic->header.source_id);
1105 goto err_edac_unreg; 1101 goto err;
1106 } 1102 }
1107 rc = request_irq(ghes->irq, ghes_irq_func, IRQF_SHARED, 1103 rc = request_irq(ghes->irq, ghes_irq_func, IRQF_SHARED,
1108 "GHES IRQ", ghes); 1104 "GHES IRQ", ghes);
1109 if (rc) { 1105 if (rc) {
1110 pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n", 1106 pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
1111 generic->header.source_id); 1107 generic->header.source_id);
1112 goto err_edac_unreg; 1108 goto err;
1113 } 1109 }
1114 break; 1110 break;
1115 1111
@@ -1132,14 +1128,16 @@ static int ghes_probe(struct platform_device *ghes_dev)
1132 default: 1128 default:
1133 BUG(); 1129 BUG();
1134 } 1130 }
1131
1135 platform_set_drvdata(ghes_dev, ghes); 1132 platform_set_drvdata(ghes_dev, ghes);
1136 1133
1134 ghes_edac_register(ghes, &ghes_dev->dev);
1135
1137 /* Handle any pending errors right away */ 1136 /* Handle any pending errors right away */
1138 ghes_proc(ghes); 1137 ghes_proc(ghes);
1139 1138
1140 return 0; 1139 return 0;
1141err_edac_unreg: 1140
1142 ghes_edac_unregister(ghes);
1143err: 1141err:
1144 if (ghes) { 1142 if (ghes) {
1145 ghes_fini(ghes); 1143 ghes_fini(ghes);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index da2da53bca6d..57304b2e989f 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -232,6 +232,7 @@ config EDAC_SBRIDGE
232config EDAC_SKX 232config EDAC_SKX
233 tristate "Intel Skylake server Integrated MC" 233 tristate "Intel Skylake server Integrated MC"
234 depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG 234 depends on PCI && X86_64 && X86_MCE_INTEL && PCI_MMCONFIG
235 depends on ACPI_NFIT || !ACPI_NFIT # if ACPI_NFIT=m, EDAC_SKX can't be y
235 select DMI 236 select DMI
236 help 237 help
237 Support for error detection and correction the Intel 238 Support for error detection and correction the Intel
@@ -374,7 +375,7 @@ config EDAC_THUNDERX
374 375
375config EDAC_ALTERA 376config EDAC_ALTERA
376 bool "Altera SOCFPGA ECC" 377 bool "Altera SOCFPGA ECC"
377 depends on EDAC=y && ARCH_SOCFPGA 378 depends on EDAC=y && (ARCH_SOCFPGA || ARCH_STRATIX10)
378 help 379 help
379 Support for error detection and correction on the 380 Support for error detection and correction on the
380 Altera SOCs. This must be selected for SDRAM ECC. 381 Altera SOCs. This must be selected for SDRAM ECC.
diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 11d6419788c2..d0d5c4dbe097 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1,20 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
3 * Copyright (C) 2017-2018, Intel Corporation. All rights reserved
2 * Copyright Altera Corporation (C) 2014-2016. All rights reserved. 4 * Copyright Altera Corporation (C) 2014-2016. All rights reserved.
3 * Copyright 2011-2012 Calxeda, Inc. 5 * Copyright 2011-2012 Calxeda, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Adapted from the highbank_mc_edac driver.
18 */ 6 */
19 7
20#include <asm/cacheflush.h> 8#include <asm/cacheflush.h>
@@ -26,6 +14,7 @@
26#include <linux/irqchip/chained_irq.h> 14#include <linux/irqchip/chained_irq.h>
27#include <linux/kernel.h> 15#include <linux/kernel.h>
28#include <linux/mfd/syscon.h> 16#include <linux/mfd/syscon.h>
17#include <linux/notifier.h>
29#include <linux/of_address.h> 18#include <linux/of_address.h>
30#include <linux/of_irq.h> 19#include <linux/of_irq.h>
31#include <linux/of_platform.h> 20#include <linux/of_platform.h>
@@ -80,6 +69,25 @@ static const struct altr_sdram_prv_data a10_data = {
80 .ue_set_mask = A10_DIAGINT_TDERRA_MASK, 69 .ue_set_mask = A10_DIAGINT_TDERRA_MASK,
81}; 70};
82 71
72static const struct altr_sdram_prv_data s10_data = {
73 .ecc_ctrl_offset = S10_ECCCTRL1_OFST,
74 .ecc_ctl_en_mask = A10_ECCCTRL1_ECC_EN,
75 .ecc_stat_offset = S10_INTSTAT_OFST,
76 .ecc_stat_ce_mask = A10_INTSTAT_SBEERR,
77 .ecc_stat_ue_mask = A10_INTSTAT_DBEERR,
78 .ecc_saddr_offset = S10_SERRADDR_OFST,
79 .ecc_daddr_offset = S10_DERRADDR_OFST,
80 .ecc_irq_en_offset = S10_ERRINTEN_OFST,
81 .ecc_irq_en_mask = A10_ECC_IRQ_EN_MASK,
82 .ecc_irq_clr_offset = S10_INTSTAT_OFST,
83 .ecc_irq_clr_mask = (A10_INTSTAT_SBEERR | A10_INTSTAT_DBEERR),
84 .ecc_cnt_rst_offset = S10_ECCCTRL1_OFST,
85 .ecc_cnt_rst_mask = A10_ECC_CNT_RESET_MASK,
86 .ce_ue_trgr_offset = S10_DIAGINTTEST_OFST,
87 .ce_set_mask = A10_DIAGINT_TSERRA_MASK,
88 .ue_set_mask = A10_DIAGINT_TDERRA_MASK,
89};
90
83/*********************** EDAC Memory Controller Functions ****************/ 91/*********************** EDAC Memory Controller Functions ****************/
84 92
85/* The SDRAM controller uses the EDAC Memory Controller framework. */ 93/* The SDRAM controller uses the EDAC Memory Controller framework. */
@@ -231,6 +239,7 @@ static unsigned long get_total_mem(void)
231static const struct of_device_id altr_sdram_ctrl_of_match[] = { 239static const struct of_device_id altr_sdram_ctrl_of_match[] = {
232 { .compatible = "altr,sdram-edac", .data = &c5_data}, 240 { .compatible = "altr,sdram-edac", .data = &c5_data},
233 { .compatible = "altr,sdram-edac-a10", .data = &a10_data}, 241 { .compatible = "altr,sdram-edac-a10", .data = &a10_data},
242 { .compatible = "altr,sdram-edac-s10", .data = &s10_data},
234 {}, 243 {},
235}; 244};
236MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match); 245MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
@@ -477,6 +486,292 @@ static int altr_sdram_remove(struct platform_device *pdev)
477 return 0; 486 return 0;
478} 487}
479 488
489/**************** Stratix 10 EDAC Memory Controller Functions ************/
490
491/**
492 * s10_protected_reg_write
493 * Write to a protected SMC register.
494 * @context: Not used.
495 * @reg: Address of register
496 * @value: Value to write
497 * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
498 * INTEL_SIP_SMC_REG_ERROR on error
499 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
500 */
501static int s10_protected_reg_write(void *context, unsigned int reg,
502 unsigned int val)
503{
504 struct arm_smccc_res result;
505
506 arm_smccc_smc(INTEL_SIP_SMC_REG_WRITE, reg, val, 0, 0,
507 0, 0, 0, &result);
508
509 return (int)result.a0;
510}
511
512/**
513 * s10_protected_reg_read
514 * Read the status of a protected SMC register
515 * @context: Not used.
516 * @reg: Address of register
517 * @value: Value read.
518 * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
519 * INTEL_SIP_SMC_REG_ERROR on error
520 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
521 */
522static int s10_protected_reg_read(void *context, unsigned int reg,
523 unsigned int *val)
524{
525 struct arm_smccc_res result;
526
527 arm_smccc_smc(INTEL_SIP_SMC_REG_READ, reg, 0, 0, 0,
528 0, 0, 0, &result);
529
530 *val = (unsigned int)result.a1;
531
532 return (int)result.a0;
533}
534
535static bool s10_sdram_writeable_reg(struct device *dev, unsigned int reg)
536{
537 switch (reg) {
538 case S10_ECCCTRL1_OFST:
539 case S10_ERRINTEN_OFST:
540 case S10_INTMODE_OFST:
541 case S10_INTSTAT_OFST:
542 case S10_DIAGINTTEST_OFST:
543 case S10_SYSMGR_ECC_INTMASK_VAL_OFST:
544 case S10_SYSMGR_ECC_INTMASK_SET_OFST:
545 case S10_SYSMGR_ECC_INTMASK_CLR_OFST:
546 return true;
547 }
548 return false;
549}
550
551static bool s10_sdram_readable_reg(struct device *dev, unsigned int reg)
552{
553 switch (reg) {
554 case S10_ECCCTRL1_OFST:
555 case S10_ERRINTEN_OFST:
556 case S10_INTMODE_OFST:
557 case S10_INTSTAT_OFST:
558 case S10_DERRADDR_OFST:
559 case S10_SERRADDR_OFST:
560 case S10_DIAGINTTEST_OFST:
561 case S10_SYSMGR_ECC_INTMASK_VAL_OFST:
562 case S10_SYSMGR_ECC_INTMASK_SET_OFST:
563 case S10_SYSMGR_ECC_INTMASK_CLR_OFST:
564 case S10_SYSMGR_ECC_INTSTAT_SERR_OFST:
565 case S10_SYSMGR_ECC_INTSTAT_DERR_OFST:
566 return true;
567 }
568 return false;
569}
570
571static bool s10_sdram_volatile_reg(struct device *dev, unsigned int reg)
572{
573 switch (reg) {
574 case S10_ECCCTRL1_OFST:
575 case S10_ERRINTEN_OFST:
576 case S10_INTMODE_OFST:
577 case S10_INTSTAT_OFST:
578 case S10_DERRADDR_OFST:
579 case S10_SERRADDR_OFST:
580 case S10_DIAGINTTEST_OFST:
581 case S10_SYSMGR_ECC_INTMASK_VAL_OFST:
582 case S10_SYSMGR_ECC_INTMASK_SET_OFST:
583 case S10_SYSMGR_ECC_INTMASK_CLR_OFST:
584 case S10_SYSMGR_ECC_INTSTAT_SERR_OFST:
585 case S10_SYSMGR_ECC_INTSTAT_DERR_OFST:
586 return true;
587 }
588 return false;
589}
590
591static const struct regmap_config s10_sdram_regmap_cfg = {
592 .name = "s10_ddr",
593 .reg_bits = 32,
594 .reg_stride = 4,
595 .val_bits = 32,
596 .max_register = 0xffffffff,
597 .writeable_reg = s10_sdram_writeable_reg,
598 .readable_reg = s10_sdram_readable_reg,
599 .volatile_reg = s10_sdram_volatile_reg,
600 .reg_read = s10_protected_reg_read,
601 .reg_write = s10_protected_reg_write,
602 .use_single_rw = true,
603};
604
605static int altr_s10_sdram_probe(struct platform_device *pdev)
606{
607 const struct of_device_id *id;
608 struct edac_mc_layer layers[2];
609 struct mem_ctl_info *mci;
610 struct altr_sdram_mc_data *drvdata;
611 const struct altr_sdram_prv_data *priv;
612 struct regmap *regmap;
613 struct dimm_info *dimm;
614 u32 read_reg;
615 int irq, ret = 0;
616 unsigned long mem_size;
617
618 id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev);
619 if (!id)
620 return -ENODEV;
621
622 /* Grab specific offsets and masks for Stratix10 */
623 priv = of_match_node(altr_sdram_ctrl_of_match,
624 pdev->dev.of_node)->data;
625
626 regmap = devm_regmap_init(&pdev->dev, NULL, (void *)priv,
627 &s10_sdram_regmap_cfg);
628 if (IS_ERR(regmap))
629 return PTR_ERR(regmap);
630
631 /* Validate the SDRAM controller has ECC enabled */
632 if (regmap_read(regmap, priv->ecc_ctrl_offset, &read_reg) ||
633 ((read_reg & priv->ecc_ctl_en_mask) != priv->ecc_ctl_en_mask)) {
634 edac_printk(KERN_ERR, EDAC_MC,
635 "No ECC/ECC disabled [0x%08X]\n", read_reg);
636 return -ENODEV;
637 }
638
639 /* Grab memory size from device tree. */
640 mem_size = get_total_mem();
641 if (!mem_size) {
642 edac_printk(KERN_ERR, EDAC_MC, "Unable to calculate memory size\n");
643 return -ENODEV;
644 }
645
646 /* Ensure the SDRAM Interrupt is disabled */
647 if (regmap_update_bits(regmap, priv->ecc_irq_en_offset,
648 priv->ecc_irq_en_mask, 0)) {
649 edac_printk(KERN_ERR, EDAC_MC,
650 "Error disabling SDRAM ECC IRQ\n");
651 return -ENODEV;
652 }
653
654 /* Toggle to clear the SDRAM Error count */
655 if (regmap_update_bits(regmap, priv->ecc_cnt_rst_offset,
656 priv->ecc_cnt_rst_mask,
657 priv->ecc_cnt_rst_mask)) {
658 edac_printk(KERN_ERR, EDAC_MC,
659 "Error clearing SDRAM ECC count\n");
660 return -ENODEV;
661 }
662
663 if (regmap_update_bits(regmap, priv->ecc_cnt_rst_offset,
664 priv->ecc_cnt_rst_mask, 0)) {
665 edac_printk(KERN_ERR, EDAC_MC,
666 "Error clearing SDRAM ECC count\n");
667 return -ENODEV;
668 }
669
670 irq = platform_get_irq(pdev, 0);
671 if (irq < 0) {
672 edac_printk(KERN_ERR, EDAC_MC,
673 "No irq %d in DT\n", irq);
674 return -ENODEV;
675 }
676
677 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
678 layers[0].size = 1;
679 layers[0].is_virt_csrow = true;
680 layers[1].type = EDAC_MC_LAYER_CHANNEL;
681 layers[1].size = 1;
682 layers[1].is_virt_csrow = false;
683 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
684 sizeof(struct altr_sdram_mc_data));
685 if (!mci)
686 return -ENOMEM;
687
688 mci->pdev = &pdev->dev;
689 drvdata = mci->pvt_info;
690 drvdata->mc_vbase = regmap;
691 drvdata->data = priv;
692 platform_set_drvdata(pdev, mci);
693
694 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
695 edac_printk(KERN_ERR, EDAC_MC,
696 "Unable to get managed device resource\n");
697 ret = -ENOMEM;
698 goto free;
699 }
700
701 mci->mtype_cap = MEM_FLAG_DDR3;
702 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
703 mci->edac_cap = EDAC_FLAG_SECDED;
704 mci->mod_name = EDAC_MOD_STR;
705 mci->ctl_name = dev_name(&pdev->dev);
706 mci->scrub_mode = SCRUB_SW_SRC;
707 mci->dev_name = dev_name(&pdev->dev);
708
709 dimm = *mci->dimms;
710 dimm->nr_pages = ((mem_size - 1) >> PAGE_SHIFT) + 1;
711 dimm->grain = 8;
712 dimm->dtype = DEV_X8;
713 dimm->mtype = MEM_DDR3;
714 dimm->edac_mode = EDAC_SECDED;
715
716 ret = edac_mc_add_mc(mci);
717 if (ret < 0)
718 goto err;
719
720 ret = devm_request_irq(&pdev->dev, irq, altr_sdram_mc_err_handler,
721 IRQF_SHARED, dev_name(&pdev->dev), mci);
722 if (ret < 0) {
723 edac_mc_printk(mci, KERN_ERR,
724 "Unable to request irq %d\n", irq);
725 ret = -ENODEV;
726 goto err2;
727 }
728
729 if (regmap_write(regmap, S10_SYSMGR_ECC_INTMASK_CLR_OFST,
730 S10_DDR0_IRQ_MASK)) {
731 edac_printk(KERN_ERR, EDAC_MC,
732 "Error clearing SDRAM ECC count\n");
733 return -ENODEV;
734 }
735
736 if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset,
737 priv->ecc_irq_en_mask, priv->ecc_irq_en_mask)) {
738 edac_mc_printk(mci, KERN_ERR,
739 "Error enabling SDRAM ECC IRQ\n");
740 ret = -ENODEV;
741 goto err2;
742 }
743
744 altr_sdr_mc_create_debugfs_nodes(mci);
745
746 devres_close_group(&pdev->dev, NULL);
747
748 return 0;
749
750err2:
751 edac_mc_del_mc(&pdev->dev);
752err:
753 devres_release_group(&pdev->dev, NULL);
754free:
755 edac_mc_free(mci);
756 edac_printk(KERN_ERR, EDAC_MC,
757 "EDAC Probe Failed; Error %d\n", ret);
758
759 return ret;
760}
761
762static int altr_s10_sdram_remove(struct platform_device *pdev)
763{
764 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
765
766 edac_mc_del_mc(&pdev->dev);
767 edac_mc_free(mci);
768 platform_set_drvdata(pdev, NULL);
769
770 return 0;
771}
772
773/************** </Stratix10 EDAC Memory Controller Functions> ***********/
774
480/* 775/*
481 * If you want to suspend, need to disable EDAC by removing it 776 * If you want to suspend, need to disable EDAC by removing it
482 * from the device tree or defconfig. 777 * from the device tree or defconfig.
@@ -508,6 +803,20 @@ static struct platform_driver altr_sdram_edac_driver = {
508 803
509module_platform_driver(altr_sdram_edac_driver); 804module_platform_driver(altr_sdram_edac_driver);
510 805
806static struct platform_driver altr_s10_sdram_edac_driver = {
807 .probe = altr_s10_sdram_probe,
808 .remove = altr_s10_sdram_remove,
809 .driver = {
810 .name = "altr_s10_sdram_edac",
811#ifdef CONFIG_PM
812 .pm = &altr_sdram_pm_ops,
813#endif
814 .of_match_table = altr_sdram_ctrl_of_match,
815 },
816};
817
818module_platform_driver(altr_s10_sdram_edac_driver);
819
511/************************* EDAC Parent Probe *************************/ 820/************************* EDAC Parent Probe *************************/
512 821
513static const struct of_device_id altr_edac_device_of_match[]; 822static const struct of_device_id altr_edac_device_of_match[];
@@ -1106,7 +1415,7 @@ static void *ocram_alloc_mem(size_t size, void **other)
1106 1415
1107static void ocram_free_mem(void *p, size_t size, void *other) 1416static void ocram_free_mem(void *p, size_t size, void *other)
1108{ 1417{
1109 gen_pool_free((struct gen_pool *)other, (u32)p, size); 1418 gen_pool_free((struct gen_pool *)other, (unsigned long)p, size);
1110} 1419}
1111 1420
1112static const struct edac_device_prv_data ocramecc_data = { 1421static const struct edac_device_prv_data ocramecc_data = {
@@ -1925,6 +2234,171 @@ static struct platform_driver altr_edac_a10_driver = {
1925}; 2234};
1926module_platform_driver(altr_edac_a10_driver); 2235module_platform_driver(altr_edac_a10_driver);
1927 2236
2237/************** Stratix 10 EDAC Device Controller Functions> ************/
2238
2239#define to_s10edac(p, m) container_of(p, struct altr_stratix10_edac, m)
2240
2241/*
2242 * The double bit error is handled through SError which is fatal. This is
2243 * called as a panic notifier to printout ECC error info as part of the panic.
2244 */
2245static int s10_edac_dberr_handler(struct notifier_block *this,
2246 unsigned long event, void *ptr)
2247{
2248 struct altr_stratix10_edac *edac = to_s10edac(this, panic_notifier);
2249 int err_addr, dberror;
2250
2251 s10_protected_reg_read(edac, S10_SYSMGR_ECC_INTSTAT_DERR_OFST,
2252 &dberror);
2253 /* Remember the UE Errors for a reboot */
2254 s10_protected_reg_write(edac, S10_SYSMGR_UE_VAL_OFST, dberror);
2255 if (dberror & S10_DDR0_IRQ_MASK) {
2256 s10_protected_reg_read(edac, S10_DERRADDR_OFST, &err_addr);
2257 /* Remember the UE Error address */
2258 s10_protected_reg_write(edac, S10_SYSMGR_UE_ADDR_OFST,
2259 err_addr);
2260 edac_printk(KERN_ERR, EDAC_MC,
2261 "EDAC: [Uncorrectable errors @ 0x%08X]\n\n",
2262 err_addr);
2263 }
2264
2265 return NOTIFY_DONE;
2266}
2267
2268static void altr_edac_s10_irq_handler(struct irq_desc *desc)
2269{
2270 struct altr_stratix10_edac *edac = irq_desc_get_handler_data(desc);
2271 struct irq_chip *chip = irq_desc_get_chip(desc);
2272 int irq = irq_desc_get_irq(desc);
2273 int bit, sm_offset, irq_status;
2274
2275 sm_offset = S10_SYSMGR_ECC_INTSTAT_SERR_OFST;
2276
2277 chained_irq_enter(chip, desc);
2278
2279 s10_protected_reg_read(NULL, sm_offset, &irq_status);
2280
2281 for_each_set_bit(bit, (unsigned long *)&irq_status, 32) {
2282 irq = irq_linear_revmap(edac->domain, bit);
2283 if (irq)
2284 generic_handle_irq(irq);
2285 }
2286
2287 chained_irq_exit(chip, desc);
2288}
2289
2290static void s10_eccmgr_irq_mask(struct irq_data *d)
2291{
2292 struct altr_stratix10_edac *edac = irq_data_get_irq_chip_data(d);
2293
2294 s10_protected_reg_write(edac, S10_SYSMGR_ECC_INTMASK_SET_OFST,
2295 BIT(d->hwirq));
2296}
2297
2298static void s10_eccmgr_irq_unmask(struct irq_data *d)
2299{
2300 struct altr_stratix10_edac *edac = irq_data_get_irq_chip_data(d);
2301
2302 s10_protected_reg_write(edac, S10_SYSMGR_ECC_INTMASK_CLR_OFST,
2303 BIT(d->hwirq));
2304}
2305
2306static int s10_eccmgr_irqdomain_map(struct irq_domain *d, unsigned int irq,
2307 irq_hw_number_t hwirq)
2308{
2309 struct altr_stratix10_edac *edac = d->host_data;
2310
2311 irq_set_chip_and_handler(irq, &edac->irq_chip, handle_simple_irq);
2312 irq_set_chip_data(irq, edac);
2313 irq_set_noprobe(irq);
2314
2315 return 0;
2316}
2317
2318static const struct irq_domain_ops s10_eccmgr_ic_ops = {
2319 .map = s10_eccmgr_irqdomain_map,
2320 .xlate = irq_domain_xlate_twocell,
2321};
2322
2323static int altr_edac_s10_probe(struct platform_device *pdev)
2324{
2325 struct altr_stratix10_edac *edac;
2326 struct device_node *child;
2327 int dberror, err_addr;
2328
2329 edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL);
2330 if (!edac)
2331 return -ENOMEM;
2332
2333 edac->dev = &pdev->dev;
2334 platform_set_drvdata(pdev, edac);
2335 INIT_LIST_HEAD(&edac->s10_ecc_devices);
2336
2337 edac->irq_chip.name = pdev->dev.of_node->name;
2338 edac->irq_chip.irq_mask = s10_eccmgr_irq_mask;
2339 edac->irq_chip.irq_unmask = s10_eccmgr_irq_unmask;
2340 edac->domain = irq_domain_add_linear(pdev->dev.of_node, 64,
2341 &s10_eccmgr_ic_ops, edac);
2342 if (!edac->domain) {
2343 dev_err(&pdev->dev, "Error adding IRQ domain\n");
2344 return -ENOMEM;
2345 }
2346
2347 edac->sb_irq = platform_get_irq(pdev, 0);
2348 if (edac->sb_irq < 0) {
2349 dev_err(&pdev->dev, "No SBERR IRQ resource\n");
2350 return edac->sb_irq;
2351 }
2352
2353 irq_set_chained_handler_and_data(edac->sb_irq,
2354 altr_edac_s10_irq_handler,
2355 edac);
2356
2357 edac->panic_notifier.notifier_call = s10_edac_dberr_handler;
2358 atomic_notifier_chain_register(&panic_notifier_list,
2359 &edac->panic_notifier);
2360
2361 /* Printout a message if uncorrectable error previously. */
2362 s10_protected_reg_read(edac, S10_SYSMGR_UE_VAL_OFST, &dberror);
2363 if (dberror) {
2364 s10_protected_reg_read(edac, S10_SYSMGR_UE_ADDR_OFST,
2365 &err_addr);
2366 edac_printk(KERN_ERR, EDAC_DEVICE,
2367 "Previous Boot UE detected[0x%X] @ 0x%X\n",
2368 dberror, err_addr);
2369 /* Reset the sticky registers */
2370 s10_protected_reg_write(edac, S10_SYSMGR_UE_VAL_OFST, 0);
2371 s10_protected_reg_write(edac, S10_SYSMGR_UE_ADDR_OFST, 0);
2372 }
2373
2374 for_each_child_of_node(pdev->dev.of_node, child) {
2375 if (!of_device_is_available(child))
2376 continue;
2377
2378 if (of_device_is_compatible(child, "altr,sdram-edac-s10"))
2379 of_platform_populate(pdev->dev.of_node,
2380 altr_sdram_ctrl_of_match,
2381 NULL, &pdev->dev);
2382 }
2383
2384 return 0;
2385}
2386
2387static const struct of_device_id altr_edac_s10_of_match[] = {
2388 { .compatible = "altr,socfpga-s10-ecc-manager" },
2389 {},
2390};
2391MODULE_DEVICE_TABLE(of, altr_edac_s10_of_match);
2392
2393static struct platform_driver altr_edac_s10_driver = {
2394 .probe = altr_edac_s10_probe,
2395 .driver = {
2396 .name = "socfpga_s10_ecc_manager",
2397 .of_match_table = altr_edac_s10_of_match,
2398 },
2399};
2400module_platform_driver(altr_edac_s10_driver);
2401
1928MODULE_LICENSE("GPL v2"); 2402MODULE_LICENSE("GPL v2");
1929MODULE_AUTHOR("Thor Thayer"); 2403MODULE_AUTHOR("Thor Thayer");
1930MODULE_DESCRIPTION("EDAC Driver for Altera Memories"); 2404MODULE_DESCRIPTION("EDAC Driver for Altera Memories");
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index cbc96290f743..81f0554e09de 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -1,23 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * 3 * Copyright (C) 2017-2018, Intel Corporation
3 * Copyright (C) 2015 Altera Corporation 4 * Copyright (C) 2015 Altera Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 5 */
17 6
18#ifndef _ALTERA_EDAC_H 7#ifndef _ALTERA_EDAC_H
19#define _ALTERA_EDAC_H 8#define _ALTERA_EDAC_H
20 9
10#include <linux/arm-smccc.h>
21#include <linux/edac.h> 11#include <linux/edac.h>
22#include <linux/types.h> 12#include <linux/types.h>
23 13
@@ -94,6 +84,7 @@
94/* SDRAM Controller Address Width Register */ 84/* SDRAM Controller Address Width Register */
95#define CV_DRAMADDRW 0xFFC2502C 85#define CV_DRAMADDRW 0xFFC2502C
96#define A10_DRAMADDRW 0xFFCFA0A8 86#define A10_DRAMADDRW 0xFFCFA0A8
87#define S10_DRAMADDRW 0xF80110E0
97 88
98/* SDRAM Controller Address Widths Field Register */ 89/* SDRAM Controller Address Widths Field Register */
99#define DRAMADDRW_COLBIT_MASK 0x001F 90#define DRAMADDRW_COLBIT_MASK 0x001F
@@ -115,6 +106,7 @@
115/* SDRAM Controller Interface Data Width Register */ 106/* SDRAM Controller Interface Data Width Register */
116#define CV_DRAMIFWIDTH 0xFFC25030 107#define CV_DRAMIFWIDTH 0xFFC25030
117#define A10_DRAMIFWIDTH 0xFFCFB008 108#define A10_DRAMIFWIDTH 0xFFCFB008
109#define S10_DRAMIFWIDTH 0xF8011008
118 110
119/* SDRAM Controller Interface Data Width Defines */ 111/* SDRAM Controller Interface Data Width Defines */
120#define CV_DRAMIFWIDTH_16B_ECC 24 112#define CV_DRAMIFWIDTH_16B_ECC 24
@@ -164,6 +156,34 @@
164#define A10_INTMASK_CLR_OFST 0x10 156#define A10_INTMASK_CLR_OFST 0x10
165#define A10_DDR0_IRQ_MASK BIT(17) 157#define A10_DDR0_IRQ_MASK BIT(17)
166 158
159/************* Stratix10 Defines **************/
160
161/* SDRAM Controller EccCtrl Register */
162#define S10_ECCCTRL1_OFST 0xF8011100
163
164/* SDRAM Controller DRAM IRQ Register */
165#define S10_ERRINTEN_OFST 0xF8011110
166
167/* SDRAM Interrupt Mode Register */
168#define S10_INTMODE_OFST 0xF801111C
169
170/* SDRAM Controller Error Status Register */
171#define S10_INTSTAT_OFST 0xF8011120
172
173/* SDRAM Controller ECC Error Address Register */
174#define S10_DERRADDR_OFST 0xF801112C
175#define S10_SERRADDR_OFST 0xF8011130
176
177/* SDRAM Controller ECC Diagnostic Register */
178#define S10_DIAGINTTEST_OFST 0xF8011124
179
180/* SDRAM Single Bit Error Count Compare Set Register */
181#define S10_SERRCNTREG_OFST 0xF801113C
182
183/* Sticky registers for Uncorrected Errors */
184#define S10_SYSMGR_UE_VAL_OFST 0xFFD12220
185#define S10_SYSMGR_UE_ADDR_OFST 0xFFD12224
186
167struct altr_sdram_prv_data { 187struct altr_sdram_prv_data {
168 int ecc_ctrl_offset; 188 int ecc_ctrl_offset;
169 int ecc_ctl_en_mask; 189 int ecc_ctl_en_mask;
@@ -296,6 +316,18 @@ struct altr_sdram_mc_data {
296/* A10 ECC Controller memory initialization timeout */ 316/* A10 ECC Controller memory initialization timeout */
297#define ALTR_A10_ECC_INIT_WATCHDOG_10US 10000 317#define ALTR_A10_ECC_INIT_WATCHDOG_10US 10000
298 318
319/************* Stratix10 Defines **************/
320
321/* Stratix10 ECC Manager Defines */
322#define S10_SYSMGR_ECC_INTMASK_VAL_OFST 0xFFD12090
323#define S10_SYSMGR_ECC_INTMASK_SET_OFST 0xFFD12094
324#define S10_SYSMGR_ECC_INTMASK_CLR_OFST 0xFFD12098
325
326#define S10_SYSMGR_ECC_INTSTAT_SERR_OFST 0xFFD1209C
327#define S10_SYSMGR_ECC_INTSTAT_DERR_OFST 0xFFD120A0
328
329#define S10_DDR0_IRQ_MASK BIT(16)
330
299struct altr_edac_device_dev; 331struct altr_edac_device_dev;
300 332
301struct edac_device_prv_data { 333struct edac_device_prv_data {
@@ -340,4 +372,78 @@ struct altr_arria10_edac {
340 struct list_head a10_ecc_devices; 372 struct list_head a10_ecc_devices;
341}; 373};
342 374
375/*
376 * Functions specified by ARM SMC Calling convention:
377 *
378 * FAST call executes atomic operations, returns when the requested operation
379 * has completed.
380 * STD call starts a operation which can be preempted by a non-secure
381 * interrupt. The call can return before the requested operation has
382 * completed.
383 *
384 * a0..a7 is used as register names in the descriptions below, on arm32
385 * that translates to r0..r7 and on arm64 to w0..w7.
386 */
387
388#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \
389 ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \
390 ARM_SMCCC_OWNER_SIP, (func_num))
391
392#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \
393 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
394 ARM_SMCCC_OWNER_SIP, (func_num))
395
396#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
397#define INTEL_SIP_SMC_STATUS_OK 0x0
398#define INTEL_SIP_SMC_REG_ERROR 0x5
399
400/*
401 * Request INTEL_SIP_SMC_REG_READ
402 *
403 * Read a protected register using SMCCC
404 *
405 * Call register usage:
406 * a0: INTEL_SIP_SMC_REG_READ.
407 * a1: register address.
408 * a2-7: not used.
409 *
410 * Return status:
411 * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
412 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
413 * a1: Value in the register
414 * a2-3: not used.
415 */
416#define INTEL_SIP_SMC_FUNCID_REG_READ 7
417#define INTEL_SIP_SMC_REG_READ \
418 INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ)
419
420/*
421 * Request INTEL_SIP_SMC_REG_WRITE
422 *
423 * Write a protected register using SMCCC
424 *
425 * Call register usage:
426 * a0: INTEL_SIP_SMC_REG_WRITE.
427 * a1: register address
428 * a2: value to program into register.
429 * a3-7: not used.
430 *
431 * Return status:
432 * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
433 * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
434 * a1-3: not used.
435 */
436#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8
437#define INTEL_SIP_SMC_REG_WRITE \
438 INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE)
439
440struct altr_stratix10_edac {
441 struct device *dev;
442 int sb_irq;
443 struct irq_domain *domain;
444 struct irq_chip irq_chip;
445 struct list_head s10_ecc_devices;
446 struct notifier_block panic_notifier;
447};
448
343#endif /* #ifndef _ALTERA_EDAC_H */ 449#endif /* #ifndef _ALTERA_EDAC_H */
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index 68b6ee18bea6..473aeec4b1da 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -91,6 +91,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
91 struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, 91 struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
92 mci->n_layers, 92 mci->n_layers,
93 dimm_fill->count, 0, 0); 93 dimm_fill->count, 0, 0);
94 u16 rdr_mask = BIT(7) | BIT(13);
94 95
95 if (entry->size == 0xffff) { 96 if (entry->size == 0xffff) {
96 pr_info("Can't get DIMM%i size\n", 97 pr_info("Can't get DIMM%i size\n",
@@ -99,22 +100,21 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
99 } else if (entry->size == 0x7fff) { 100 } else if (entry->size == 0x7fff) {
100 dimm->nr_pages = MiB_TO_PAGES(entry->extended_size); 101 dimm->nr_pages = MiB_TO_PAGES(entry->extended_size);
101 } else { 102 } else {
102 if (entry->size & 1 << 15) 103 if (entry->size & BIT(15))
103 dimm->nr_pages = MiB_TO_PAGES((entry->size & 104 dimm->nr_pages = MiB_TO_PAGES((entry->size & 0x7fff) << 10);
104 0x7fff) << 10);
105 else 105 else
106 dimm->nr_pages = MiB_TO_PAGES(entry->size); 106 dimm->nr_pages = MiB_TO_PAGES(entry->size);
107 } 107 }
108 108
109 switch (entry->memory_type) { 109 switch (entry->memory_type) {
110 case 0x12: 110 case 0x12:
111 if (entry->type_detail & 1 << 13) 111 if (entry->type_detail & BIT(13))
112 dimm->mtype = MEM_RDDR; 112 dimm->mtype = MEM_RDDR;
113 else 113 else
114 dimm->mtype = MEM_DDR; 114 dimm->mtype = MEM_DDR;
115 break; 115 break;
116 case 0x13: 116 case 0x13:
117 if (entry->type_detail & 1 << 13) 117 if (entry->type_detail & BIT(13))
118 dimm->mtype = MEM_RDDR2; 118 dimm->mtype = MEM_RDDR2;
119 else 119 else
120 dimm->mtype = MEM_DDR2; 120 dimm->mtype = MEM_DDR2;
@@ -123,20 +123,29 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
123 dimm->mtype = MEM_FB_DDR2; 123 dimm->mtype = MEM_FB_DDR2;
124 break; 124 break;
125 case 0x18: 125 case 0x18:
126 if (entry->type_detail & 1 << 13) 126 if (entry->type_detail & BIT(12))
127 dimm->mtype = MEM_NVDIMM;
128 else if (entry->type_detail & BIT(13))
127 dimm->mtype = MEM_RDDR3; 129 dimm->mtype = MEM_RDDR3;
128 else 130 else
129 dimm->mtype = MEM_DDR3; 131 dimm->mtype = MEM_DDR3;
130 break; 132 break;
133 case 0x1a:
134 if (entry->type_detail & BIT(12))
135 dimm->mtype = MEM_NVDIMM;
136 else if (entry->type_detail & BIT(13))
137 dimm->mtype = MEM_RDDR4;
138 else
139 dimm->mtype = MEM_DDR4;
140 break;
131 default: 141 default:
132 if (entry->type_detail & 1 << 6) 142 if (entry->type_detail & BIT(6))
133 dimm->mtype = MEM_RMBS; 143 dimm->mtype = MEM_RMBS;
134 else if ((entry->type_detail & ((1 << 7) | (1 << 13))) 144 else if ((entry->type_detail & rdr_mask) == rdr_mask)
135 == ((1 << 7) | (1 << 13)))
136 dimm->mtype = MEM_RDR; 145 dimm->mtype = MEM_RDR;
137 else if (entry->type_detail & 1 << 7) 146 else if (entry->type_detail & BIT(7))
138 dimm->mtype = MEM_SDR; 147 dimm->mtype = MEM_SDR;
139 else if (entry->type_detail & 1 << 9) 148 else if (entry->type_detail & BIT(9))
140 dimm->mtype = MEM_EDO; 149 dimm->mtype = MEM_EDO;
141 else 150 else
142 dimm->mtype = MEM_UNKNOWN; 151 dimm->mtype = MEM_UNKNOWN;
@@ -172,8 +181,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg)
172 } 181 }
173} 182}
174 183
175void ghes_edac_report_mem_error(struct ghes *ghes, int sev, 184void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
176 struct cper_sec_mem_err *mem_err)
177{ 185{
178 enum hw_event_mc_err_type type; 186 enum hw_event_mc_err_type type;
179 struct edac_raw_error_desc *e; 187 struct edac_raw_error_desc *e;
@@ -183,10 +191,8 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
183 char *p; 191 char *p;
184 u8 grain_bits; 192 u8 grain_bits;
185 193
186 if (!pvt) { 194 if (!pvt)
187 pr_err("Internal error: Can't find EDAC structure\n");
188 return; 195 return;
189 }
190 196
191 /* 197 /*
192 * We can do the locking below because GHES defers error processing 198 * We can do the locking below because GHES defers error processing
@@ -434,12 +440,16 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
434 struct mem_ctl_info *mci; 440 struct mem_ctl_info *mci;
435 struct edac_mc_layer layers[1]; 441 struct edac_mc_layer layers[1];
436 struct ghes_edac_dimm_fill dimm_fill; 442 struct ghes_edac_dimm_fill dimm_fill;
437 int idx; 443 int idx = -1;
438 444
439 /* Check if safe to enable on this system */ 445 if (IS_ENABLED(CONFIG_X86)) {
440 idx = acpi_match_platform_list(plat_list); 446 /* Check if safe to enable on this system */
441 if (!force_load && idx < 0) 447 idx = acpi_match_platform_list(plat_list);
442 return 0; 448 if (!force_load && idx < 0)
449 return -ENODEV;
450 } else {
451 idx = 0;
452 }
443 453
444 /* 454 /*
445 * We have only one logical memory controller to which all DIMMs belong. 455 * We have only one logical memory controller to which all DIMMs belong.
@@ -519,6 +529,9 @@ void ghes_edac_unregister(struct ghes *ghes)
519{ 529{
520 struct mem_ctl_info *mci; 530 struct mem_ctl_info *mci;
521 531
532 if (!ghes_pvt)
533 return;
534
522 mci = ghes_pvt->mci; 535 mci = ghes_pvt->mci;
523 edac_mc_del_mc(mci->pdev); 536 edac_mc_del_mc(mci->pdev);
524 edac_mc_free(mci); 537 edac_mc_free(mci);
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 8c5540160a23..4d0ea3563d47 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1743,7 +1743,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
1743 err = "write parity error"; 1743 err = "write parity error";
1744 break; 1744 break;
1745 case 19: 1745 case 19:
1746 err = "redundacy loss"; 1746 err = "redundancy loss";
1747 break; 1747 break;
1748 case 20: 1748 case 20:
1749 err = "reserved"; 1749 err = "reserved";
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8feb0c866ee0..1624e2be485c 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -55,22 +55,21 @@ enum {
55/* From drivers/edac/ghes_edac.c */ 55/* From drivers/edac/ghes_edac.c */
56 56
57#ifdef CONFIG_EDAC_GHES 57#ifdef CONFIG_EDAC_GHES
58void ghes_edac_report_mem_error(struct ghes *ghes, int sev, 58void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
59 struct cper_sec_mem_err *mem_err);
60 59
61int ghes_edac_register(struct ghes *ghes, struct device *dev); 60int ghes_edac_register(struct ghes *ghes, struct device *dev);
62 61
63void ghes_edac_unregister(struct ghes *ghes); 62void ghes_edac_unregister(struct ghes *ghes);
64 63
65#else 64#else
66static inline void ghes_edac_report_mem_error(struct ghes *ghes, int sev, 65static inline void ghes_edac_report_mem_error(int sev,
67 struct cper_sec_mem_err *mem_err) 66 struct cper_sec_mem_err *mem_err)
68{ 67{
69} 68}
70 69
71static inline int ghes_edac_register(struct ghes *ghes, struct device *dev) 70static inline int ghes_edac_register(struct ghes *ghes, struct device *dev)
72{ 71{
73 return 0; 72 return -ENODEV;
74} 73}
75 74
76static inline void ghes_edac_unregister(struct ghes *ghes) 75static inline void ghes_edac_unregister(struct ghes *ghes)